元数据.有关对象/方法/属性的数据.
例如,我可以声明一个名为:DisplayOrder的属性,以便轻松控制属性在UI中的显示顺序.然后,我可以将其附加到一个类中,并编写一些GUI组件来提取属性,并对UI元素进行适当排序.
public class DisplayWrapper
{
private UnderlyingClass underlyingObject;
public DisplayWrapper(UnderlyingClass u)
{
underlyingObject = u;
}
[DisplayOrder(1)]
public int SomeInt
{
get
{
return underlyingObject .SomeInt;
}
}
[DisplayOrder(2)]
public DateTime SomeDate
{
get
{
return underlyingObject .SomeDate;
}
}
}
从而确保在使用我的自定义GUI组件时,SomeInt始终显示在SomeDate之前.
但是,您将看到它们在直接编码环境之外最常用.例如,Windows Designer广泛使用它们,因此它知道如何处理定制对象.像这样使用BrowsableAttribute:
[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
get{/*do something*/}
}
例如,告诉设计器不要在设计时将其列在"属性"窗口的可用属性中.
您还可以将它们用于代码生成、预编译操作(如Post Sharp)或运行时操作(如反射).发出
public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
bool time = true;
foreach (Attribute a in target.GetCustomAttributes())
{
if (a.GetType() is NoTimingAttribute)
{
time = false;
break;
}
}
if (time)
{
StopWatch stopWatch = new StopWatch();
stopWatch.Start();
targetMethod.Invoke(target, args);
stopWatch.Stop();
HandleTimingOutput(targetMethod, stopWatch.Duration);
}
else
{
targetMethod.Invoke(target, args);
}
}
声明它们很容易,只需创建一个继承自属性的类.
public class DisplayOrderAttribute : Attribute
{
private int order;
public DisplayOrderAttribute(int order)
{
this.order = order;
}
public int Order
{
get { return order; }
}
}
请记住,当您使用该属性时,可以省略后缀"ATTRIBUTE",编译器会为您添加后缀"ATTRIBUTE".
NOTE:个属性本身不做任何事情——需要有其他代码使用它们.有时这些代码是为您编写的,但有时您必须自己编写.例如,C#编译器关心某些框架,而某些框架使用某些框架(例如,NUnit在加载程序集时在类上查找[TestFixture],在测试方法上查找[Test])