C# Attribute特性实战(1):Swtich判断优化

2024-01-08 23:31:06

前言

在经过前面两章内容的讲解,我们已经简单了解了如何使用特性和反射。我们这里解决一个简单的案例

C#高级语法 Attribute特性详解和类型,方法,变量附加特性讲解

C# 反射的终点:Type,MethodInfo,PropertyInfo,ParameterInfo,Summry

简单Switch问题

我们经常会遇到Switch的代码过于冗长的问题,就算使用Enum枚举类型,也无法优化Switch代码。如果Switch类型继续增长,我们的swtich代码就会跟着变长

在这里插入图片描述

无参Swtich方法

声明Swtich Attribute

namespace NetCore.MyAttributes
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class MySwitchAttribute:Attribute
    {
        public enum SwichFlags { Apple, Banana, Pear, Ball }

        public SwichFlags Flag { get; set; }
        public MySwitchAttribute(SwichFlags swichFlags)
        {
            Flag = swichFlags;
        }

        public MySwitchAttribute() { }
        
    }
}

声明带有Swtich特性方法

这里用到了这个文章封装好的静态方法

C#高级语法 Attribute特性详解和类型,方法,变量附加特性讲解


namespace NetCore.Services
{
    
    public class SwitchService
    {
     

        public SwitchService() {
        
        }

        /// <summary>
        /// 用于解决Switch过长的问题
        /// </summary>
        /// <param name="flags"></param>
        public void SwitchLoop(MySwitchAttribute.SwichFlags flags)
        {
        	//此方法为自定义的方法
            var methods = MyAttributeHelper.GetAll_MethodAndAtt<MySwitchAttribute>(typeof(SwitchService));

            var method = methods.Find(t =>
            {
                return t.att.Flag == flags;
            });

            //找到那个目标的Switch方法
            if(method.method == null)
            {
                Console.WriteLine($"找不到该方法{flags.ToString()}");
            }
            else
            {
                method.method.Invoke(this,null);
            }
        }

        /// <summary>
        /// 注意,能用找到的方法必然是public
        /// </summary>

        [MySwitch(MySwitchAttribute.SwichFlags.Apple)]
        public void SwitchApple()
        {
            Console.WriteLine("苹果");
        }

        [MySwitch(MySwitchAttribute.SwichFlags.Banana)]
        public void SwitchBanana()
        {
            Console.WriteLine("香蕉");

        }

        [MySwitch(MySwitchAttribute.SwichFlags.Pear)]
        public void SwitchPear()
        {
            Console.WriteLine("梨");

        }


    }
}

主方法

static void Main(string[] args)
{
    var serivce = new SwitchService();
    //Apple修饰的方法是有的
    serivce.SwitchLoop(MySwitchAttribute.SwichFlags.Apple);
    //Ball修饰的方法是没有的
    serivce.SwitchLoop(MySwitchAttribute.SwichFlags.Ball);
    //var methods = MyAttributeHelper.GetAllMethods<MySwitchAttribute>(typeof(SwitchService));
    Console.WriteLine("运行完成!");
    Console.ReadKey();
}

结果

在这里插入图片描述

有参Switch

有参Switch,或者说能通过某种方法把参数传进去。个人不建议使用方法的方式入参,使用本身属性的方法入参更好。

修改代码

  public class SwitchService
  {
   
      public string Name { get; set; }    
      public SwitchService() {
      
      }

      /// <summary>
      /// 用于解决Switch过长的问题
      /// </summary>
      /// <param name="flags"></param>
      public void SwitchLoop(MySwitchAttribute.SwichFlags flags)
      {
          var methods = MyAttributeHelper.GetAll_MethodAndAtt<MySwitchAttribute>(typeof(SwitchService));
          //此方法为自定义的方法
          var method = methods.Find(t =>
          {
              return t.att.Flag == flags;
          });

          //找到那个目标的Switch方法
          if(method.method == null)
          {
              Console.WriteLine($"找不到该方法{flags.ToString()}");
          }
          else
          {
              method.method.Invoke(this,null);
          }
      }

      /// <summary>
      /// 注意,能用找到的方法必然是public
      /// </summary>

      [MySwitch(MySwitchAttribute.SwichFlags.Apple)]
      public void SwitchApple()
      {
          Console.WriteLine($"Name:{Name}");
          Console.WriteLine("苹果");
      }

      [MySwitch(MySwitchAttribute.SwichFlags.Banana)]
      public void SwitchBanana()
      {
          Console.WriteLine($"Name:{Name}");

          Console.WriteLine("香蕉");

      }

      [MySwitch(MySwitchAttribute.SwichFlags.Pear)]
      public void SwitchPear()
      {
          Console.WriteLine($"Name:{Name}");

          Console.WriteLine("梨");

      }


  }

修改运行过程

    static void Main(string[] args)
    {
        var serivce = new SwitchService();
        //Apple修饰的方法是有的,尝试使用属性的方式入参
        serivce.Name = "小王";
        serivce.SwitchLoop(MySwitchAttribute.SwichFlags.Apple);
        //Ball修饰的方法是没有的
        serivce.Name = "小红";
        serivce.SwitchLoop(MySwitchAttribute.SwichFlags.Ball);
        //var methods = MyAttributeHelper.GetAllMethods<MySwitchAttribute>(typeof(SwitchService));
        Console.WriteLine("运行完成!");
        Console.ReadKey();
    }

运行结果

在这里插入图片描述

总结

我们这里讲解了一下简单的Switch简化,我们平常遇到的长Switch可能有2,30个以上的条件判断。使用Attribute可以大大增强我们代码的可读性。

入参问题个人还是建议使用方法获取本身属性,函数入参写起来会过于麻烦。

文章来源:https://blog.csdn.net/qq_44695769/article/details/135397868
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。