公共语言运行时使你能够添加类似于关键字的描述性声明(称为特性),以便批注编程元素(如类型、字段、方法和属性)。 .NET 出于多种原因且为解决许多问题而使用特性。 特性描述如何将数据序列化、指定用于强制安全性的特征并限制通过实时 (JIT) 编译器进行优化,从而使代码易于调试。 特性还可记录文件的名称或代码的作者,或控制窗体开发过程中控件和成员的可见性。

1、特性(Attribute)

 使用特性,可以有效地将元数据或声明性信息与代码(程序集、类型、方法、属性等)相关联。 将特性与程序实体相关联后,可以在运行时使用 反射 这项技术查询特性。

特性具有以下属性:

1)特性向程序添加元数据。 元数据 是程序中定义的类型的相关信息。 所有 .NET 程序集都包含一组指定的元数据,用于描述程序集中定义的类型和类型成员。 可以添加自定义特性来指定所需的其他任何信息。

2)可以将一个或多个特性应用于整个程序集、模块或较小的程序元素(如类和属性)。

3)特性可以像方法和属性一样接受自变量。

4)程序可使用反射来检查自己的元数据或其他程序中的元数据。

使用特性(Attribute):

可以将特性附加到几乎任何声明中,尽管特定特性可能会限制可有效附加到的声明的类型。 在 C# 中,通过用方括号 ([]) 将特性名称括起来,并置于应用该特性的实体的声明上方以指定特性。

例如,

[Serializable]
public class SampleClass
{
      private string code = "csharp";
      private string name = "cjavapy";
      private int age = 0; 
}

2、常用特性标签(Attribute)

1)控件开发常用Attribute

BrowsableAttribute :描述是否一个属性或事件应该被显示在属性浏览器里。

CategoryAttribute :描述一个属性或事件的类别,当使用类别的时候,属性浏览器按类别将属性分组。

DescriptionAttribute :当用户在属性浏览器里选择属性的时候,description里指定的文本会显示在属性浏览器的下边,向用户显示属性的功能。

BindableAttribute :描述是否一个属性倾向于被绑定。

DefaultPropertyAttribute :为组件指定一个默认的属性,当用户在Form设计器上选择一个控件的时候,默认属性会在属性浏览器里被选中。   

DefaultValueAttribute :为一个简单类型的属性设置一个默认值。

EditorAttribute :为属性指定一个特殊的编辑器。

LocalizableAttribute :指示一个属性是否能被本地化,任何有这个Attribute的属性将会被持久化到资源文件里。 

DesignerSerializationVisibilityAttribute:指示一个属性是否或者如何持久化到代码里。

指示一个属性是否串行化和如何串行化,它的值是一个枚举,一共有三种类型Content,Hidden,Visible。Content指示代码生成器为对象包 含 的内容生成代码,而不是为对象本身,Hidden指示代码生成器不为对象生成代码,visible指示代码生成器为对象生成代码。假如你的控件 有一 个集合属性,又想在设计时自动将集合属性的内容生成代码,那么就使用这个Attribute,并将值设为DesignerSerializationVisibility.Content。

TypeConverterAttribute :为属性指定一个类型转换器,类型转换器能将属性的值转化成其它的数据类型。

DefaultEventAttribute :为组件指定一个默认的事件,当用户在form设计其中选择一个控件的时候,在属性浏览器中这个事件被选中。

2) Web services常用Attribute

WebMethodAttribute:向使用 ASP.NET 创建的 XML Web service 中的某个方法添加此特性后,就可以从远程 Web 客户端调用该方法。 此类不能被继承。

WebServiceAttribute:用于向 XML Web services 添加附加信息,如描述其功能的字符串。

WebServiceBindingAttribute:声明用于定义一个或多个 XML Web service 方法的绑定。 此类不能被继承。

3)调用非托管代码Attribute

DllImportAttribute:指示由非托管动态链接库 (DLL) 公开为静态入口点的特性化方法。

4)类和方法常用Attribute

ObsoleteAttribute:标记不再使用的程序元素。 此类不能被继承。一般标记不推荐使用的方法或类。

ParamArrayAttribute:指示方法在其调用中将允许数目可变的自变量。 此类不能被继承。

SerializableAttribute:表示类可以序列化。 此类不能被继承。

5)Xml操作常用Attribute

XmlElementAttribute:指示公共字段或属性在 XmlSerializer 序列化或反序列化包含它们的对象时表示 XML 元素。

XmlIgnoreAttribute:指示 Serialize(TextWriter, Object) 的 XmlSerializer 方法不序列化公共字段或公共读/写属性值。

XmlIncludeAttribute:允许 XmlSerializer 在它序列化或反序列化对象时识别类型。

XmlNamespaceDeclarationsAttribute:指定目标属性、参数、返回值或类成员包含与 XML 文档中使用的命名空间相关联的前缀。

XmlRootAttribute:控制视为 XML 根元素的属性目标的 XML 序列化。

XmlTextAttribute:当串行化或反序列化包含该成员的类时,向 XmlSerializer 指示应将该成员作为 XML 文本处理。

XmlTypeAttribute:控制当属性目标由 XmlSerializer 序列化时生成的 XML 架构。

3、创建自定义特性

可通过定义特性类创建自己的自定义特性,特性类是直接或间接派生自 Attribute 的类,可快速轻松地识别元数据中的特性定义。 假设希望使用编写类型的程序员的姓名来标记该类型。 可能需要定义一个自定义 Author 特性类:

例如,

[System.AttributeUsage(System.AttributeTargets.Class |  
                       System.AttributeTargets.Struct)  
]  
public class AuthorAttribute : System.Attribute  
{  
    private string name;  
    public double version;  
    public AuthorAttribute(string name)  
    {  
        this.name = name;  
        version = 1.0;  
    }  
}  

注意:类名 AuthorAttribute 是该特性的名称,即 Author 加上 Attribute 后缀。 由于该类派生自 System.Attribute,因此它是一个自定义特性类。

1)第一个参数 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。可以使用|指定多个。

2)参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。

3)inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。

使用Attribute方法如下:

[Author("cjavapy", version = 1.0)]  
class SampleClass  
{  
      private string code = "csharp";
      private string name = "cjavapy";
      private int age = 0;
}  

AttributeUsage 有一个命名参数 AllowMultiple,通过此命名参数可一次或多次使用自定义特性。

例如,

[System.AttributeUsage(System.AttributeTargets.Class |  
                       System.AttributeTargets.Struct,  
                       AllowMultiple = true)  // 可以使用多个Attribute
]  
public class AuthorAttribute : System.Attribute  

使用时一个可以指定多个标签,

例如,

[Author("cjavapy", version = 1.1)]  
[Author("levi", version = 1.2)]
class SampleClass
{
private string code = "csharp";
private string name = "cjavapy";
private int age = 0;
}

推荐文档