一尘不染

.NET中的属性是什么?

c#

.NET中的属性是什么,它们有什么用,以及如何创建自己的属性?


阅读 425

收藏
2020-05-19

共1个答案

一尘不染

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

例如,我可以声明一个名为: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组件时,始终在SomeDate之前显示SomeInt。

但是,您将看到它们在直接编码环境之外最常用。例如,Windows
Designer广泛使用它们,因此它知道如何处理自定义对象。像这样使用BrowsableAttribute:

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

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

可能
还使用它们生成代码,预编译操作(如后夏普)或运行时操作如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”,编译器将为您添加该属性。

注意: 属性本身不会做任何事情-
需要使用它们的一些其他代码。有时已经为您编写了该代码,但有时您必须自己编写。例如,C#编译器关心某些框架,某些框架使用某些框架(例如,在加载程序集时,NUnit在类上查找[TestFixture],在测试方法上查找[Test])。
因此,在创建自己的自定义属性时,请注意它根本不会影响代码的行为。您需要编写另一部分来检查属性(通过反射)并对其进行操作。

2020-05-19