C# Attribute

目标:
①学会定义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());  // 站立
        }