C# 特性(Attribute)
特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。
具体详情请跳到--文档DOC
.Net提供了三种预定义特性:
-
AttributeUsage: 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。
-
Conditional:标记了一个条件方法,其执行依赖于指定的预处理标识符。它会引起方法调用的条件编译,取决于指定的值,比如 Debug 或 Trace。例如,当调试代码时显示变量的值。
-
Obsolete:标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。例如,当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个应该使用新方法,而不是旧方法的消息,来把它标记为 obsolete(过时的)。
使用AttributeUsage:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class TestUsageAttribute : System.Attribute
{
}
[AttributeUsage
(
validon,//指定特性允许的目标类型。构造函数的第一个参数必须是AttributeTarget类型的枚举值
AllowMultiple=allowmultiple,//布尔值,指示特性能否被派生类和重写成员继承
Inherited=inherited//布尔值,指示特性能否被重复放置在同一个程序实体前多次
)]
貌似现在C# 4.2定义AttributeUsage,构造函数中只能指定validon,可以指定多个!在VS按下F12进去可以看到具体参数类型
//
// 摘要:
// 指定可应用属性的应用程序元素。
[ComVisible(true)]
[Flags]
public enum AttributeTargets
{
//
// 摘要:
// 特性可以应用于程序集。
Assembly = 1,
//
// 摘要:
// 特性可以应用于模块中。
Module = 2,
//
// 摘要:
// 特性可以应用于类。
Class = 4,
//
// 摘要:
// 特性可以应用于结构;即,类型值。
Struct = 8,
//
// 摘要:
// 特性可以应用于枚举。
Enum = 16,
//
// 摘要:
// 特性可以应用于构造函数。
Constructor = 32,
//
// 摘要:
// 特性可以应用于方法。
Method = 64,
//
// 摘要:
// 特性可以应用于属性。
Property = 128,
//
// 摘要:
// 特性可以应用于字段。
Field = 256,
//
// 摘要:
// 特性可以应用于事件。
Event = 512,
//
// 摘要:
// 特性可以应用于接口。
Interface = 1024,
//
// 摘要:
// 特性可以应用于参数。
Parameter = 2048,
//
// 摘要:
// 特性可以应用于委托。
Delegate = 4096,
//
// 摘要:
// 特性可以应用于返回的值。
ReturnValue = 8192,
//
// 摘要:
// 特性可以应用于泛型参数。
GenericParameter = 16384,
//
// 摘要:
// 特性可以应用于任何应用程序元素。
All = 32767
}
namespace TsstAttribute
{
class Program
{
static void Main(string[] args)
{
Test mc = new Test();
Type t = mc.GetType();
Object[] obj = t.GetCustomAttributes(false);
foreach (Attribute a in obj)
{
TestUsageAttribute attr = a as TestUsageAttribute;
if (attr != null)
{
Console.WriteLine("Description : {0}", attr.Des);
}
}
Console.ReadKey();
}
}
}
[TestUsage("测试")]
public class Test
{
}
[AttributeUsage(AttributeTargets.Class)]
public class TestUsageAttribute : System.Attribute
{
public string Des;
public TestUsageAttribute(string _des)
{
Des = _des;
}
}
输出结果为:
使用Obsolete:
过期或者弃用的方法直接可以进行提示。
使用Condition:(此处直接看的菜鸟教程)
#define DEBUG
using System;
using System.Diagnostics;
public class Myclass
{
[Conditional("DEBUG")]
public static void Message(string msg)
{
Console.WriteLine(msg);
}
}
class Test
{
static void function1()
{
Myclass.Message("In Function 1.");
function2();
}
static void function2()
{
Myclass.Message("In Function 2.");
}
public static void Main()
{
Myclass.Message("In Main function.");
function1();
Console.ReadKey();
}
}
可以看到输出结果为:
In Main function In Function 1 In Function 2
//使用自定位特性
namespace TsstAttribute
{
class Program
{
static void Main(string[] args)
{
System.Reflection.MemberInfo info = typeof(Ghost);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++)
{
NpcArrtibute a = attributes[i] as NpcArrtibute;
if (a != null)
Console.WriteLine(string.Format("种族:{0},等级:{1}", a.Name, a.Level.ToString()));
}
System.Reflection.MemberInfo info1 = typeof(Beast);
object[] attributes1 = info1.GetCustomAttributes(true);
for (int i = 0; i < attributes1.Length; i++)
{
NpcArrtibute a = attributes1[i] as NpcArrtibute;
if (a != null)
Console.WriteLine(string.Format("种族:{0},等级:{1}", a.Name, a.Level.ToString()));
}
Console.ReadKey();
}
}
}
[NpcArrtibute(name:"Ghost",level:10)]
public class Ghost
{
}
[NpcArrtibute(name: "Beast", level: 5)]
public class Beast
{
}
public class NpcArrtibute:System.Attribute
{
public string Name;
public int Level;
public NpcArrtibute(string name,int level)
{
Name = name;
Level = level;
}
}
输出结果:
特性使用基本跟反射在一起使用,在游戏开发或者需要对类、方法、结构、枚举、组件进行打上特定标签进行处理可使用特性进行处理!具体详情可以查看官方文档