在.NET 中,特性(Attribute)是一种强大的机制,用于在代码中添加元数据。以下是 Attribute 的一些高级使用:
1. 自定义特性
- 创建自定义特性类:通过继承
System.Attribute
类来创建自定义特性。例如,创建一个用于标记方法是否已过时的自定义特性。
[AttributeUsage(AttributeTargets.Method)] public class ObsoleteMethodAttribute : Attribute { public string Message { get; set; } public ObsoleteMethodAttribute(string message) { Message = message; } }
- 在上述代码中,
AttributeUsage
特性用于指定自定义特性ObsoleteMethodAttribute
可以应用于方法(AttributeTargets.Method
)。这个自定义特性有一个属性Message
,用于存储方法已过时的相关信息。 - 应用自定义特性:
class MyClass { [ObsoleteMethod("This method is obsolete. Use NewMethod instead.")] public void OldMethod() { } public void NewMethod() { } }
- 这里在
MyClass
的OldMethod
方法上应用了ObsoleteMethodAttribute
特性,传递了一个表示过时信息的字符串。
2. 通过反射读取特性
- 获取类型中的特性信息:可以使用反射来检查类型是否应用了特定的特性,并读取特性中的信息。
class Program { static void Main() { Type myClassType = typeof(MyClass); MethodInfo oldMethodInfo = myClassType.GetMethod("OldMethod"); if (oldMethodInfo.IsDefined(typeof(ObsoleteMethodAttribute), false)) { ObsoleteMethodAttribute obsoleteAttr = (ObsoleteMethodAttribute)oldMethodInfo.GetCustomAttribute(typeof(ObsoleteMethodAttribute)); Console.WriteLine(obsoleteAttr.Message); } } }
- 首先,通过
typeof
操作符获取MyClass
的类型信息,然后使用GetMethod
获取OldMethod
的MethodInfo
。接着,通过IsDefined
检查方法是否应用了ObsoleteMethodAttribute
,如果是,则使用GetCustomAttribute
获取特性实例并读取其中的Message
属性。
3. 条件编译与特性结合
- 在.NET 中,可以使用条件编译符号结合特性来实现更灵活的代码控制。例如,在调试版本和发布版本中对代码进行不同的处理。
[Conditional("DEBUG")] public static void DebugOnlyMethod() { Console.WriteLine("This method only executes in debug builds."); }
- 当编译时定义了
DEBUG
符号(通常在调试配置下),DebugOnlyMethod
方法会被包含在编译后的代码中;如果没有定义DEBUG
符号(如在发布配置下),对DebugOnlyMethod
的调用会被编译器忽略。
4. 多个特性应用
- 一个代码元素(如类、方法、属性等)可以应用多个特性。
[Serializable] [Obsolete("This class is obsolete. Use AnotherClass instead.")] class MyOldClass { }
- 这里
MyOldClass
同时应用了Serializable
特性(表示该类可以被序列化)和Obsolete
特性(表示该类已过时)。
5. 特性继承
- 控制特性继承行为:在定义自定义特性时,可以通过
AttributeUsage
的Inherited
参数来控制特性是否可以被继承。
[AttributeUsage(AttributeTargets.Class, Inherited = false)] public class NonInheritedAttribute : Attribute { }
- 对于上述
NonInheritedAttribute
,如果一个类应用了该特性,它的子类不会自动继承这个特性。如果Inherited
设置为true
(默认值为true
,除了少数如AttributeUsage
本身等特性),子类会继承父类的特性。