目标:
①学会定义Attribute。
②使用Attribute
③利用Attribute实现简单功能。
前提:会用反射。
目标①:定义Attribute
Attribute是类,需要继承自Attribute,类名通常以Attribute结尾。如下,定义了ShowNameAttribute类。
public class ShowNameAttribute:Attribute{ public string Name { get; set; } public ShowNameAttribute(string name) { this.Name = name; } }
目标②:使用Attribute
使用Attribute时,需要用[]把Attribute的类名括起来(类名中的Attribute可省略),然后放到类,属性,方法等上面。如果构造函数有参数,则在()中指定参数。
public enum EnumAction { [ShowNameAttribute("睡觉")] Sleep, [ShowName("站立")] Stand, Eat }
上面代码的结果是EnumAction.Sleep 和 EnumAction.Stand都拥有了Attribute,Attribute可以用反射取得,然后就可以使用Attribute的属性和方法了。
目标③:利用Attribute实现简单功能。
3.1)背景
使用枚举时,有时需要打印枚举成员所对应的名字。
例如下面代码,我想让Sleep打印“睡觉”,让Stand打印“站立”。
public enum EnumAction { Sleep, Stand, Eat }
3.2)实现
小白通常的做法是用if语句,下面看用Attribute来实现。
①在enum成员上使用Attribute
public enum EnumAction { [ShowNameAttribute("睡觉")] Sleep, [ShowName("站立")] Stand, Eat }
②为enum追加扩展方法,该扩展方法用来打印Attribute标记的名字。
public static class EnumActionExtensions { public static string ShowName(this EnumAction status) { string str = status.ToString(); var att = status.GetType().GetMember(str).First().GetCustomAttribute<ShowNameAttribute>(); //利用反射找status上名称为ShowNameAttribute的Attribute。 if (att != null) { return att.Name;//如果该成员存在ShowNameAttribute,则显示ShowNameAttribute中定义的值 } else { return str;//不存在,显示成员名 } } }
③测试
由于Eat没有标记ShowNameAttribute,所以打印的仍为英文,而Sleep和Stand标记了ShowNameAttribute,所以打印的是中文。
public static void TestShowStatus() { Console.WriteLine("EnumAction.Eat:" + EnumAction.Eat.ShowName()); //Eat。因为Eat上面没有追加Attribute。 Console.WriteLine("EnumAction.Sleep:" + EnumAction.Sleep.ShowName()); //睡觉 Console.WriteLine("EnumAction.Stand:" + EnumAction.Stand.ShowName()); // 站立 }