C#中的属性

36 .net c# attributes

我知道C#(和.NET一般)在属性上很重要.然而,尽管我已用C#编程多年,但我还没有发现自己曾经使用它们.有人会让我开始使用它们,并解释哪些是最好的使用它们?

谢谢

Ron*_*rby 33

来自Pro C#2008和.NET 3.5平台,由Andrew Troelsen编写的第四版

理解归属编程

.NET编译器的一个作用是为所有已定义和引用的类型生成元数据描述.除了任何程序集中包含的此标准元数据之外,.NET平台还为程序员提供了一种使用属性将其他元数据嵌入到程序集中的方法.简而言之,属性只不过是可以应用于给定类型(类,接口,结构等),成员(属性,方法等),程序集或模块的代码注释.使用属性注释代码的想法并不新鲜.COM IDL提供了许多预定义属性,允许开发人员描述给定COM服务器中包含的类型.但是,COM属性只不过是一组关键字.如果COM开发人员需要创建自定义属性,他或她可以这样做,但它在代码中被128位数字(GUID)引用,这在最好情况下很麻烦.与COM IDL属性(它们只是关键字)不同,.NET属性是扩展抽象System.Attribute基类的类类型.在浏览.NET命名空间时,您会发现许多预定义属性,您可以在应用程序中使用这些属性.此外,您可以自由地构建自定义属性,以通过创建从Attribute派生的新类型来进一步限定类型的行为.了解当您在代码中应用属性时,嵌入的元数据基本上是无用的,直到另一个软件明确反映信息.如果不是这种情况,那么嵌入在程序集中的元数据的模糊将被忽略并且完全无害.

属性消费者

正如您所猜测的那样,.NET 3.5 Framework SDK附带了许多实用程序,这些实用程序确实在寻找各种属性.C#编译器(csc.exe)本身已经过预编程,可以在编译周期中发现各种属性的存在.例如,如果C#编译器遇到[CLSCompliant]属性,它将自动检查属性项以确保它仅公开符合CLS的构造.通过另一个示例,如果C#编译器发现使用[Obsolete]属性归属的项目,它将在Visual Studio 2008错误列表窗口中显示编译器警告.除了开发工具之外,.NET基类库中的许多方法都是预编程的,以反映特定的属性.例如,如果您希望将对象的状态保持为文件,则您需要做的就是使用[Serializable]属性为您的类添加注释.如果BinaryFormatter类的Serialize()方法遇到此属性,则该对象将自动保持为紧凑二进制格式的文件..NET CLR也因某些属性的存在而徘徊.也许最着名的.NET属性是[WebMethod].如果您希望通过HTTP请求公开方法并自动将方法返回值编码为XML,只需将[WebMethod]应用于该方法,CLR将处理详细信息.除了Web服务开发之外,属性对于.NET安全系统,Windows Communication Foundation和COM/.NET互操作性(等等)的运行至关重要.最后,您可以自由地构建编程的应用程序,以反映您自己的自定义属性以及.NET基类库中的任何属性.通过这样做,您基本上可以创建一组由一组特定程序集理解的"关键字".

在C#中应用属性

.NET基类库在各种名称空间中提供了许多属性.下面是一些快照 - 但绝对不是所有预定义的属性.

预定义属性的微小采样

[CLSCompliant]

强制注释项符合公共语言规范(CLS)的规则.回想一下,保证在所有.NET编程语言中无缝使用符合CLS的类型.

[的DllImport]

允许.NET代码调用任何非托管的基于C或C++的代码库,包括底层操作系统的API.请注意,与基于COM的软件通信时不使用[DllImport].

[作废]

标记已弃用的类型或成员.如果其他程序员试图使用这样的项目,他们将收到编译器警告,描述他们的方式错误.

[序列化]

将类或结构标记为"可序列化",这意味着它能够将其当前状态保持为流.

[非序列化]

指定在序列化过程中不应保留类或结构中的给定字段.

[的WebMethod]

将方法标记为可通过HTTP请求调用,并指示CLR将方法返回值序列化为XML.

构建自定义属性

构建自定义属性的第一步是创建一个派生自System.Attribute的新类.例:

// A custom attribute.
public sealed class VehicleDescriptionAttribute : System.Attribute
{
    private string msgData;

    public VehicleDescriptionAttribute(string description)
    {
        msgData = description;
    }

    public VehicleDescriptionAttribute() { }

    public string Description
    {
        get { return msgData; }
        set { msgData = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,VehicleDescriptionAttribute维护一个私有内部字符串(msgData),可以使用自定义构造函数设置并使用类型属性(描述)进行操作.除了这个类派生自System.Attribute之外,这个类定义没有任何独特之处.

出于安全原因,将所有自定义属性设计为密封是一种.NET最佳实践.实际上,Visual Studio 2008提供了一个名为Attribute的代码片段,它将转储出一个新的System.属性派生类进入代码窗口.


Joe*_*orn 7

属性在针对其他程序员或程序的不同部分之间的代码中得到更多使用,而不是针对最终用户的代码.

例如,您可以使用属性来导入dll,指示类型如何与visual studio交互(设计器可见,智能感知帮助,调试器步进等),如何序列化它们,指示类型已过时,描述默认值,描述,处理COM访问等.

这些对于最终用户来说基本上是不可见的,并且单个程序员可以将其他地方放在源代码中.但是当只有编译的二进制文件可用而不是源代码时,它们才有用.