[DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true)]
[assembly: SomeAttr] // Applied to assembly [module: SomeAttr] // Applied to module [type: SomeAttr] // Applied to type sealed class SomeType<[typevar: SomeAttr] T> // Applied to generic type variable { [field: SomeAttr] // Applied to field public int SomeField = 0; [return: SomeAttr] // Applied to return value [method: SomeAttr] public int SomeMethod( [param: SomeAttr] // Applied to parameter int SomeParam) { return SomeParam; } [property: SomeAttr] // Applied to property public string SomeProp { [method: SomeAttr] // Applied to get accessor method get { return null; } } [event: SomeAttr] // Applied to event [field: SomeAttr] // Applied to compiler-generated field [method: SomeAttr] // Applied to compiler-generated add & remove methods public event EventHandler SomeEvent; }
可以利用特性对代码进行说明(注释)或在代码设计或调试期间辅助开发。
一、条件特性
#define BUGED using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; namespace MyAttribute { public class Program { static void Main(string[] args) { ToolKit.FunA(); ToolKit.FunB(); ToolKit.FunC(); ToolKit.FunD(); Console.ReadKey(); } } class ToolKit { [ConditionalAttribute("X")] // Attribute名称的长记法 [ConditionalAttribute("BUGED")] public static void FunA() { Console.WriteLine("Created By X, Buged."); } [Conditional("X")] // Attribute名称的短记法 [Conditional("NOBUG")] public static void FunB() { Console.WriteLine("Created By X, NoBug."); } [Conditional("Y")] [Conditional("BUGED")] public static void FunC() { Console.WriteLine("Created By Y, Buged."); } [Conditional("Y"), Conditional("NOBUG5")] public static void FunD() { Console.WriteLine("Created By Y, NoBug."); } } }
二、定制自己的特性
可以将特性想像成逻辑状态容器。特性类应该很简单,只提供一个公共构造器来接受特新的强制性(或定位性)状态信息,可以提供公共字段或属性以接受可选(或命名)状态信息。
// 自定义特性类 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true)] internal class TestAttribute : Attribute { } [Test] [Serializable] internal class BaseType { [Test] protected virtual void DoSomething() { } } internal class DerivedType : BaseType { protected override void DoSomething() { } }
如果自定义特性类时没有使用AttributeUsageAttribute, 编译器和CLR将假定该特性能应用于所有目标元素,而且可以继承。
AttributeUsageAttribute实现http://referencesource.microsoft.com/#System,namespaces
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: AttributeUsageAttribute ** ** ** Purpose: The class denotes how to specify the usage of an attribute ** ** ===========================================================*/ namespace System { using System.Reflection; /* By default, attributes are inherited and multiple attributes are not allowed */ [Serializable] [AttributeUsage(AttributeTargets.Class, Inherited = true)] [System.Runtime.InteropServices.ComVisible(true)] public sealed class AttributeUsageAttribute : Attribute { internal AttributeTargets m_attributeTarget = AttributeTargets.All; // Defaults to all internal bool m_allowMultiple = false; // Defaults to false internal bool m_inherited = true; // Defaults to true internal static AttributeUsageAttribute Default = new AttributeUsageAttribute(AttributeTargets.All); //Constructors public AttributeUsageAttribute(AttributeTargets validOn) { m_attributeTarget = validOn; } internal AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited) { m_attributeTarget = validOn; m_allowMultiple = allowMultiple; m_inherited = inherited; } //Properties public AttributeTargets ValidOn { get{ return m_attributeTarget; } } public bool AllowMultiple { get { return m_allowMultiple; } set { m_allowMultiple = value; } } public bool Inherited { get { return m_inherited; } set { m_inherited = value; } } } }
AttributeTargets实现http://referencesource.microsoft.com/#System,namespaces
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// namespace System { using System; // Enum used to indicate all the elements of the // VOS it is valid to attach this element to. [Serializable] [Flags] [System.Runtime.InteropServices.ComVisible(true)] public enum AttributeTargets { Assembly = 0x0001, Module = 0x0002, Class = 0x0004, Struct = 0x0008, Enum = 0x0010, Constructor = 0x0020, Method = 0x0040, Property = 0x0080, Field = 0x0100, Event = 0x0200, Interface = 0x0400, Parameter = 0x0800, Delegate = 0x1000, ReturnValue = 0x2000, //@todo GENERICS: document GenericParameter GenericParameter = 0x4000, All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate | ReturnValue | GenericParameter, } }<span style="font-size:18px;"> </span>
参考:《CLR via C#》
后面补充对反射的利用检测定制特性