在经过前面两章内容的讲解,我们已经简单了解了如何使用特性和反射。我们这里解决一个简单的案例
我们经常会遇到Switch的代码过于冗长的问题,就算使用Enum枚举类型,也无法优化Switch代码。如果Switch类型继续增长,我们的swtich代码就会跟着变长
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() { }
}
}
这里用到了这个文章封装好的静态方法
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,或者说能通过某种方法把参数传进去。个人不建议使用方法的方式入参,使用本身属性的方法入参更好。
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可以大大增强我们代码的可读性。
入参问题个人还是建议使用方法获取本身属性,函数入参写起来会过于麻烦。