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


当前回答

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

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

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

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

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

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

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

其他回答

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

您可以使用自定义属性作为在子类中定义标记值的简单方法,而不必为每个子类反复编写相同的代码。我看到John Waters写的一个很好的简洁示例,介绍了如何在自己的代码中定义和使用自定义属性。

在http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx上有一个教程

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

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

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

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

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

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

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

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

例如,我可以声明一个名为: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.

本质上,属性是您想要附加到类型(类、方法、事件、枚举等)的数据位。

其思想是,在运行时,一些其他类型/框架/工具将在属性中查询您的类型的信息并对其进行操作。

因此,例如,Visual Studio可以查询第三方控件上的属性,以确定控件的哪些属性应该在设计时出现在“属性”窗格中。

属性还可以在面向方面编程中使用,在运行时根据装饰它们的属性注入/操作对象,并向对象添加验证、日志记录等,而不影响对象的业务逻辑。