1.特性允许把定制的元数据与程序元素联系起来,这些元数据是在编译时创建的,并嵌入到程序中;
2.在运行期间可以使用反射的一些功能检查这些元数据。
3.实例:
WhatsNewAttribute.dll:定义特性, 编译:csc /t:library WhatsNewAttributes.cs;
VectorClass.dll:应用特性,编译:csc /reference:WhatsNewAttributes.dll VectorClass.cs;
LookUpWhatsNew.exe:编译:csc /reference:WhatsNewAttributes.dll /reference:VectorClass.dll LookUpWhatsNew.cs。
WhatsNewAttribute.cs:
- using System;
- namespace Magci.Test.Reflection
- {
- //定义LastModified特性类
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
- public class LastModifiedAttribute : Attribute
- {
- private DateTime dateModified;
- private string changes;
- private string issues;
- public LastModifiedAttribute(string dateModified, string changes)
- {
- this.dateModified = DateTime.Parse(dateModified);
- this.changes = changes;
- }
- public DateTime DateModified
- {
- get
- {
- return dateModified;
- }
- }
- public string Changes
- {
- get
- {
- return changes;
- }
- }
- public string Issues
- {
- get
- {
- return issues;
- }
- set
- {
- issues = value;
- }
- }
- }
- //定义SupportsWhatsNew特性类
- [AttributeUsage(AttributeTargets.Assembly)]
- public class SupportsWhatsNewAttribute : Attribute
- {
- }
- }
VectorClass.cs:
- using System;
- using System.Text;
- using System.Collections;
- using Magci.Test.Reflection;
- //使用SupportsWhatsNew特性标记
- [assembly:SupportsWhatsNew]
- namespace Magci.Test.Reflection
- {
- //添加LastModified特性
- [LastModified("2009-01-12", "IEnumerable interface implemented. So Vector can now be treated as a collection")]
- [LastModified("2009-01-08", "IFormattable interface implemented. So Vector now responds to format specifiers N and VE")]
- public class Vector : IFormattable, IEnumerable
- {
- public double x, y, z;
- public Vector(double x, double y, double z)
- {
- this.x = x;
- this.y = y;
- this.z = z;
- }
- [LastModified("2009-01-08", "Method added in order to provide formatting support")]
- public string ToString(string format, IFormatProvider formatProvider)
- {
- if (format == null)
- {
- return ToString();
- }
- string formatUpper = format.ToUpper();
- switch (formatUpper)
- {
- case "N":
- return "||" + (x*x + y*y + z*z) + "||";
- case "VE":
- return String.Format("{0:E},{1:E},{2:E}", x, y, z);
- case "IJK":
- StringBuilder sb = new StringBuilder(x.ToString(), 30);
- sb.Append("i+");
- sb.Append(y.ToString());
- sb.Append("j+");
- sb.Append(z.ToString());
- sb.Append("k");
- return sb.ToString();
- default:
- return ToString();
- }
- }
- public IEnumerator GetEnumerator()
- {
- return new VectorEnumerator(this);
- }
- public override string ToString()
- {
- return "(" + x + "," + y + "," + z + ")";
- }
- public double this [uint i]
- {
- get
- {
- switch (i)
- {
- case 0:
- return x;
- case 1:
- return y;
- case 2:
- return z;
- default:
- throw new IndexOutOfRangeException("Vector Only have three emlement!");
- }
- }
- set
- {
- switch (i)
- {
- case 0:
- x = value;
- break;
- case 1:
- y = value;
- break;
- case 2:
- z = value;
- break;
- default:
- throw new IndexOutOfRangeException("Vector Only have three emlement!");
- }
- }
- }
- }
- [LastModified("2009-01-12", "Class created as part of collection support for Vector")]
- public class VectorEnumerator : IEnumerator
- {
- Vector vector;
- int location;
- public VectorEnumerator(Vector vector)
- {
- this.vector = vector;
- location = -1;
- }
- public bool MoveNext()
- {
- ++location;
- return (location > 2) ? false : true;
- }
- public object Current
- {
- get
- {
- if (location < 0 || location > 2)
- {
- throw new InvalidOperationException("Vector only have three components!");
- }
- return vector[(uint)location];
- }
- }
- public void Reset()
- {
- location = -1;
- }
- }
- }
LookUpWhatsNew.cs:
- using System;
- using System.Reflection;
- using System.Text;
- using System.Windows.Forms;
- namespace Magci.Test.Reflection
- {
- public class WhatsNewChecker
- {
- public static StringBuilder OutputText = new StringBuilder(1000);
- //查询起始时间
- public static DateTime BackDateTo = new DateTime(2009, 1, 1);
- public static void Main()
- {
- //加载程序集
- Assembly theAssembly = Assembly.Load("VectorClass");
- //验证是否应用了SupportsWhatsNewAttribute特性
- Attribute supportsAttribute = Attribute.GetCustomAttribute(theAssembly, typeof(SupportsWhatsNewAttribute));
- string Name = theAssembly.FullName;
- OutputText.Append("/nAssembly:" + Name);
- if (supportsAttribute == null)
- {
- OutputText.Append("/nThis assembly does not support WhatsNew attributes");
- return;
- }
- else
- {
- OutputText.Append("/nDefined Types:");
- }
- //取得程序集中定义的所有类型
- Type[] types = theAssembly.GetTypes();
- //迭代显示所有类型信息
- foreach (Type type in types)
- {
- DisplayTypeInfo(theAssembly, type);
- }
- //通过消息框显示该程序集信息
- MessageBox.Show(OutputText.ToString(), "What/'s New since " + BackDateTo.ToLongDateString());
- }
- //显示类型信息
- public static void DisplayTypeInfo(Assembly theAssembly, Type type)
- {
- //只考虑类的情况
- if (!(type.IsClass))
- {
- return;
- }
- OutputText.Append("/nclass " + type.Name);
- //获取程序集的特性
- Attribute[] attributes = Attribute.GetCustomAttributes(type);
- if (attributes.Length == 0)
- {
- OutputText.Append("/nNo changes to this class");
- }
- else
- {
- //迭代显示类特性信息
- foreach (Attribute attribute in attributes)
- {
- WriteAttributeInfo(attribute);
- }
- }
- //取得程序集中所有公共方法
- MethodInfo[] methods = type.GetMethods();
- OutputText.Append("/nChanges to method of this class:");
- //迭代显示所有方法信息
- foreach (MethodInfo method in methods)
- {
- object[] attributes2 = method.GetCustomAttributes(typeof(LastModifiedAttribute), false);
- if (attributes2 != null)
- {
- OutputText.Append("/n" + method.ReturnType + " " + method.Name + "()");
- //迭代显示方法特性信息
- foreach (Attribute attribute in attributes2)
- {
- WriteAttributeInfo(attribute);
- }
- }
- }
- }
- public static void WriteAttributeInfo(Attribute attribute)
- {
- LastModifiedAttribute lastModifiedAttribute = attribute as LastModifiedAttribute;
- if (lastModifiedAttribute == null)
- {
- return;
- }
- DateTime modifiedDate = lastModifiedAttribute.DateModified;
- if (modifiedDate < BackDateTo)
- {
- return;
- }
- OutputText.Append("/nModified: " + modifiedDate.ToLongDateString() + ":");
- OutputText.Append("/n " + lastModifiedAttribute.Changes);
- if (lastModifiedAttribute.Issues != null)
- {
- OutputText.Append("/n Outstanding issues:" + lastModifiedAttribute.Issues);
- }
- }
- }
- }