C# 特性 Attribute Anotation
特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。
其它语言也叫注解 anotation
特性(Attribute)语法
特性(Attribute)的语法如下:
csharp
[attribute(positional_parameters, name_parameter = value, ...)]
element特性(Attribute)的名称和值是在方括号内规定的,放置在它所应用的元素之前。positional_parameters 规定必需的信息,name_parameter 规定可选的信息。
预定义特性(Attribute)
.Net 框架提供了三种预定义特性:
- AttributeUsage
- Conditional
- Obsolete
AttributeUsage
预定义特性 AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。 当我们要自己定义Attribute的时候我们就需要用到它了。
规定该特性的语法如下:
csharp
[AttributeUsage(validon,AllowMultiple=allowmultiple,Inherited=inherited)]其中:
- 参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。
- 参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。
- 参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。 例如:
csharp
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]条件编译 Conditional
这个预定义特性标记了一个条件方法,其执行依赖于指定的预处理标识符。
它会引起方法调用的条件编译,取决于指定的值,比如 Debug 或 Trace。例如,当调试代码时显示变量的值。
规定该特性的语法如下:
csharp
[Conditional(conditionalSymbol)]示例
csharp
namespace Malema.net
{
public class Myclass
{
[Conditional("DEBUG")]
public static void Message(string msg)
{
Console.WriteLine(msg);
}
}
class Program
{
static async Task Main(string[] args)
{
Myclass.Message("hello");
Console.ReadLine();
}
}
}上面的代码在Debug模式下,会输出 hello。在Release模式下不会输出hello

Obsolete
这个预定义特性标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。例如,当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个应该使用新方法,而不是旧方法的消息,来把它标记为 obsolete(过时的)。
规定该特性的语法如下:
csharp
[Obsolete(message)]
[Obsolete(message,iserror)]其中:
- 参数 message,是一个字符串,描述项目为什么过时以及该替代使用什么。
- 参数 iserror,是一个布尔值。如果该值为 true,编译器应把该项目的使用当作一个错误。默认值是 false(编译器生成一个警告)。 下面的实例演示了该特性:
csharp
[Obsolete("过期了,请使用YourClass.Abc")]
public class Myclass
{
public static void Message(string msg)
{
Console.WriteLine(msg);
}
}
class Program
{
static async Task Main(string[] args)
{
Myclass.Message("helo");
Console.ReadLine();
}
}我们会看到如下图这样的编译警告提示

自定义特性(Attribute)
Net 框架允许创建自定义特性,用于存储声明性的信息,且可在运行时被检索。该信息根据设计标准和应用程序需要,可与任何目标元素相关。
创建并使用自定义特性包含四个步骤:
- 声明自定义特性
- 构建自定义特性
- 在目标程序元素上应用自定义特性
- 通过反射访问特性 最后一个步骤包含编写一个简单的程序来读取元数据以便查找各种符号。元数据是用于描述其他数据的数据和信息。该程序应使用反射来在运行时访问特性。我们将在下一章详细讨论这点。
声明自定义特性
一个新的自定义特性应派生自 System.Attribute 类。例如:
csharp
[AttributeUsage(AttributeTargets.Property)]
public class CsvAttribute : Attribute
{
public CsvAttribute(string name)
{
this.Name = name;
}
public string Name { get; set; }
}应用这个特性
csharp
public class Bar
{
[Csv("openprice")]
public float Open { get; set; }
[Csv("closeprice")]
public float Close { get; set; }
}我们看到上面我们自定义的CsvAttribute类。但是在使用的时候我们可以把Attribute省略掉。
如何让这个特性有效果。得靠反射。我们下一章会有完整的例子来展示反射和使用特性。
