文章目录
- 前言
- 简单Switch问题
- 无参Swtich方法
- 声明Swtich Attribute
- 声明带有Swtich特性方法
- 主方法
- 结果
- 有参Switch
- 修改代码
- 修改运行过程
- 运行结果
- 总结
前言
在经过前面两章内容的讲解,我们已经简单了解了如何使用特性和反射。我们这里解决一个简单的案例
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可以大大增强我们代码的可读性。
入参问题个人还是建议使用方法获取本身属性,函数入参写起来会过于麻烦。