C# 知识特性 Attribute

Posted 水木山川

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 知识特性 Attribute相关的知识,希望对你有一定的参考价值。

C#知识--获取特性 Attribute

特性提供功能强大的方法,用以将元数据或声明信息与代码(程序集、类型、方法、属性等)相关联。特性与程序实体关联后,可在运行时使用“反射”查询特性,获取特性集合方法是GetCustomAttributes();

根据约定,所有特性名称都以单词“Attribute”结束,以便将它们与“.NET Framework”中的其他项区分。但是,在代码中使用特性时,不需要指定 attribute 后缀。在声明特性类时要以“Attribute”结束,使用时省略“Attribute”单词。

下面是几种使用特性的方法,菜鸟只是多看了一下总结一下,大神可以绕过:

类、程序集上的特性采用方法:

 1         /// <summary>
 2         /// 获取特性值方法
 3         /// </summary>
 4         /// <param name="t"></param>
 5         /// <returns></returns>
 6         public static string OutputDescription(Type t)
 7         {
 8             var attributes = t.GetCustomAttributes();
 9             foreach (Attribute attribute in attributes)
10             {
11                 var attr = attribute as DescriptionAttribute;
12                 if (attr != null)
13                 {
14                     return attr.Description;
15                 }
16             }
17             return t.ToString();
18         }
View Code

方法、属性采用扩展方法:

  1 /// <summary>
  2     /// 第一种获取特性值,适用只有单个特性
  3     /// </summary>
  4     public static class FingerGuessingGameTypeExtension
  5     {
  6         public static string GetEnumDescription(this FingerGuessingGameType enumType)
  7         {
  8             Type type = enumType.GetType();
  9             MemberInfo[] memberInfo = type.GetMember(enumType.ToString());
 10             if (memberInfo != null && memberInfo.Length > 0)
 11             {
 12                 object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
 13                 if (attrs != null && attrs.Length > 0)
 14                 {
 15                     return ((DescriptionAttribute)attrs[0]).Description;
 16                 }
 17             }
 18 
 19             return enumType.ToString();
 20         }
 21 
 22         public static string GetEnumValue(this FingerGuessingGameType enumType)
 23         {
 24             Type type = enumType.GetType();
 25             MemberInfo[] memberInfo = type.GetMember(enumType.ToString());
 26             if (memberInfo != null && memberInfo.Length > 0)
 27             {
 28                 object[] attrs = memberInfo[0].GetCustomAttributes(typeof(NameAttribute), false);
 29                 if (attrs != null && attrs.Length > 0)
 30                 {
 31                     return ((NameAttribute)attrs[0]).Name;
 32                 }
 33             }
 34 
 35             return enumType.ToString();
 36         }
 37     }
 38     /// <summary>
 39     /// 第二种获取特性值,适用有多个特性
 40     /// </summary>
 41     public static class FingerExtension
 42     {
 43         private static Dictionary<Enum, ValueDescriptionPair> m_Dic=null;
 44 
 45         public static string GetDescription(this FingerGuessingGameType enumType)
 46         {
 47             if (m_Dic == null)
 48             {
 49                 Type type = enumType.GetType();
 50                 var allValues = Enum.GetValues(type).OfType<Enum>();
 51                 m_Dic = allValues.ToDictionary(p => p, p => GetDescriptionValue(type, p));
 52             }
 53 
 54             ValueDescriptionPair valueDescription;
 55             if (m_Dic.TryGetValue(enumType, out valueDescription))
 56             {
 57                 return valueDescription.Description;
 58             }
 59             return enumType.ToString(); 
 60         }
 61 
 62         public static string GetValue(this FingerGuessingGameType enumType)
 63         {
 64             if (m_Dic == null)
 65             {
 66                 Type type = enumType.GetType();
 67                 var allValues = Enum.GetValues(type).OfType<Enum>();
 68                 m_Dic = allValues.ToDictionary(p => p, p => GetDescriptionValue(type, p));
 69             }
 70 
 71             ValueDescriptionPair valueDescription;
 72             if (m_Dic.TryGetValue(enumType, out valueDescription))
 73             {
 74                 return valueDescription.Name;
 75             }
 76             return enumType.ToString(); 
 77         }
 78         
 79         private static ValueDescriptionPair GetDescriptionValue(Type type, Enum value)
 80         {
 81             var valueDescriptionPair=new ValueDescriptionPair();
 82             var enumName=Enum.GetName(type,value);
 83             var description=type.GetField(enumName)
 84                 .GetCustomAttributes(typeof (DescriptionAttribute), false)
 85                 .OfType<DescriptionAttribute>().FirstOrDefault();
 86             var enumValue = type.GetField(enumName)
 87                 .GetCustomAttributes(typeof(NameAttribute), false)
 88                 .OfType<NameAttribute>().FirstOrDefault();
 89 
 90             if (description != null)
 91             {
 92                 valueDescriptionPair.Description = description.Description;
 93             }
 94             if (enumValue != null)
 95             {
 96                 valueDescriptionPair.Name = enumValue.Name;
 97             }
 98             return valueDescriptionPair;
 99         }
100     }
101 
102     public class NameAttribute:Attribute
103     {
104         public NameAttribute(string name)
105         {
106             Name = name;
107         }
108         public string Name { get; set; }
109     }
110 
111     public class ValueDescriptionPair
112     {
113         //Description 特性
114         public string Description { get; set; }
115         //Value 特性
116         public string Name { get; set; }
117     }
View Code

 序列化XML(XMLSerialize):

 1 using System;
 2 using System.IO;
 3 using System.Xml;
 4 using System.Xml.Serialization;
 5 
 6 public static class XMLSerializeExtension
 7 {
 8     public static string Serialize<T>(this T value)
 9     {
10         var result = string.Empty;
11         if (value == null)
12         {
13             return result;
14         }
15         try
16         {
17             var serializer = new XmlSerializer(typeof(T));
18             var stringWriter = new StringWriter();
19             using (var writer = XmlWriter.Create(stringWriter))
20             {
21                 serializer.Serialize(writer, value);
22                 result = stringWriter.ToString();
23             }
24         }
25         catch (Exception ex)
26         {
27             throw new Exception("An error occurred while XML serialize", ex);
28         }
29         return result;
30     }
31 
32     public static T Deserialize<T>(this string value)
33     {
34         T retObj = default(T);
35         if (string.IsNullOrWhiteSpace(value) == true)
36         {
37             return retObj;
38         }
39         try
40         {
41             using (var rdr = new StringReader(value))
42             {
43                 var serializer = new XmlSerializer(typeof(T));
44                 retObj = (T)serializer.Deserialize(rdr);
45             }
46         }
47         catch (Exception ex)
48         {
49             throw new Exception("An error occurred while XML Deserialize", ex);
50         }
51         return retObj;
52     }
53 }
View Code

反射调用方法(Reflection)

 1             Assembly assembly = Assembly.Load("ConsoleFileDemo");
 2             Type classType = assembly.GetType("ConsoleFileDemo.XmlOperator");
 3             ICase obj = Activator.CreateInstance(classType) as ICase;
 4             //获取默认方法并调用方法
 5             MethodInfo showMethod = classType.GetMethod("Show");
 6             showMethod.Invoke(assembly, new object[]{"parameter"});
 7             //获取无参方法并调用无参方法
 8             MethodInfo show1 = classType.GetMethod("Show1",new Type[]{});
 9             show1.Invoke(assembly,null);
10             //获取指定参数的方法并调用  int,string
11             MethodInfo show2 = classType.GetMethod("Show2", new Type[] {typeof (int)});
12             show2.Invoke(assembly, new object[] {10});
13 
14             MethodInfo show3 = classType.GetMethod("Show3", new Type[] { typeof(string) });
15             show3.Invoke(assembly, new object[] {"name"});
16             //获取指定私有方法并调用   string
17             MethodInfo show4 = classType.GetMethod("Show4",
18                 BindingFlags.Instance |BindingFlags.Public | BindingFlags.NonPublic,
19                 null,new Type[]{typeof(string)}, null);
20             show4.Invoke(assembly,new object[]{"name"});
21 
22             //创建单例模式,反射使用私有构造函数实例化单例
23             Type typeSingle = assembly.GetType("ConsoleFileDemo.Singleton");
24             object objectSingle = Activator.CreateInstance(typeSingle, true);            
View Code

 

以上是关于C# 知识特性 Attribute的主要内容,如果未能解决你的问题,请参考以下文章

C# 知识体系构建| 反射 上

C# 自定义特性(Attribute)详解

C#之特性(Attribute)

《Inside C#》笔记 Attribute

反骨仔的全文目录索引(持续整理中...)

C#中Attribute介绍