.NET中的属性是什么,它们有什么好处,我如何创建自己的属性?


当前回答

要开始创建一个属性,打开一个c#源文件,输入attribute并点击[TAB]。它将展开为一个新属性的模板。

其他回答

属性是一个类,它包含一些可以应用于代码中的对象的功能。要创建一个类,请创建一个继承自System.Attribute的类。

至于它们有什么好处……它们的用途几乎是无限的。

http://www.codeproject.com/KB/cs/dotnetattributes.aspx

元数据。关于对象/方法/属性的数据。

例如,我可以声明一个名为:DisplayOrder的属性,这样我就可以很容易地控制属性应该在UI中出现的顺序。然后,我可以将它附加到一个类中,并编写一些提取属性并对UI元素进行适当排序的GUI组件。

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设计器广泛使用它们,因此它知道如何处理自定义对象。像这样使用BrowsableAttribute:

[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
    get{/*do something*/}
}

例如,告诉设计器在设计时不要在“属性”窗口的可用属性中列出此属性。

您还可以将它们用于代码生成、预编译操作(如Post-Sharp)或运行时操作(如Reflection.Emit)。 例如,您可以编写一些用于分析的代码,透明地包装代码所做的每个调用并计时。你可以通过设置在特定方法上的属性来“退出”计时。

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);
    }
}

声明它们很简单,只需创建一个从Attribute继承的类。

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

记住,当你使用属性时,你可以省略后缀“attribute”,编译器会为你添加。

NOTE: Attributes don't do anything by themselves - there needs to be some other code that uses them. Sometimes that code has been written for you but sometimes you have to write it yourself. For example, the C# compiler cares about some and certain frameworks frameworks use some (e.g. NUnit looks for [TestFixture] on a class and [Test] on a test method when loading an assembly). So when creating your own custom attribute be aware that it will not impact the behaviour of your code at all. You'll need to write the other part that checks attributes (via reflection) and act on them.

属性也通常用于面向方面编程。要获得这样的示例,请查看PostSharp项目。

很多人都回答了,但到目前为止还没有人提到这个问题……

属性与反射一起被大量使用。反射已经相当慢了。

将自定义属性标记为密封类以提高其运行时性能是非常值得的。

考虑在哪里使用place这样的属性是合适的,并通过AttributeUsage来指定属性(!),这也是一个好主意。可用属性用法的列表可能会让你大吃一惊:

组装 模块 类 结构体 枚举 构造函数 方法 财产 场 事件 接口 参数 委托 ReturnValue GenericParameter 所有

AttributeUsage属性是AttributeUsage属性签名的一部分,这也很酷。哇,循环依赖!

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute

如前所述,属性相对容易创建。工作的另一部分是创建使用它的代码。在大多数情况下,您将在运行时使用反射来根据属性或其属性的存在来改变行为。在某些情况下,您将检查已编译代码上的属性以进行某种静态分析。例如,参数可能被标记为非空,分析工具可以将此作为提示。

使用这些属性并了解使用它们的适当场景是大部分工作。