.NET基础 (18)特性

时间:2023-03-08 23:48:16
.NET基础 (18)特性

特性
1 什么是特性,如何自定义一个特性
2 .NET中特性可以在哪些元素上使用
3 有哪几种方法可以获知一个元素是否申明某个特性
4 一个元素是否可以重复申明同一个特性

特性
1 什么是特性,如何自定义一个特性

特性是一种特殊的用以申明式编程的机制,特性类型是一族继承自System.Attribute的类型,在编译时,特性的使用会被写入元数据中,以共运行或者程序中的反射使用。自定义一个特性,本质上是定义一个继承自System.Attribute的类型。

自定义特性示例:

    /// <summary>
/// 自定义的特性
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class MyAttribute : Attribute
{
private String _classname;
public MyAttribute(String s)
{
_classname = s;
}
//一个只读属性
public String ClassName
{
get
{
return _classname;
}
}
} /// <summary>
/// 使用自定义属性
/// </summary>
[MyAttribute("UseMyAttribute")]
class UseMyAttribute
{
static void Main(string[] args)
{
Type t = typeof(UseMyAttribute);
Object[] attributes = t.GetCustomAttributes(false);
MyAttribute att = (MyAttribute)attributes[];
Console.WriteLine(att.ClassName);
Console.Read();
}
}

输出:

UseMyAttribute

特性将被写入元数据中,所以特性的使用基本都基于反射机制。

有几点需要注意:

  • 按照惯例,特性的名字都以Attribute结尾。
  • C#中,为了使用方便,可以省略特性名字后缀Attribute,如 [MyAttribute("UseMyAttribute")] 可写为 [My("UseMyAttribute")]。
  • 特性自身可以添加其他特性。

2 .NET中特性可以在哪些元素上使用

特性可以应用在程序集、模块、结构、枚举、构造方法、方法、属性、字段、事件、接口、参数、委托、返回参数和泛型参数这些目标元素上。通过AttributeUsage特性可以限制自定义特性的使用范围。

示例:

using System;

//应用在程序集上
[assembly: MyAttribute]
//应用在模块上
[module: MyAttribute] //应用在类型上
[type: MyAttribute]
class AttributeTargets<[typevar: MyAttribute] T> //泛型参数上
{
//应用在字段上
[field: MyAttribute]
private String _MyString; //应用在构造方法上
[method: MyAttribute]
public AttributeTargets()
{
} //应用在属性上
[property: MyAttribute]
public String MyString
{
get
{
return _MyString;
}
} //应用在方法上
[return: MyAttribute]
public String Format(
//应用在方法参数上
[param: MyAttribute]String f)
{
return null;
} //应用在事件上
[event: MyAttribute]
public event EventHandler MyEvent;
} /// <summary>
/// 一个空的特性
/// 可用于所有元素
/// </summary>
public class MyAttribute : System.Attribute
{
} public class MainClass
{
static void Main(string[] args)
{
}
}

3 有哪几种方法可以获知一个元素是否申明某个特性

System.Attribute.IsDefined

System.Attribute.GetCustomAttribute

System.Attribute.GetCustomAttributes

System.Reflection.CustomAttributeData

示例:

    [My("GetAttributes")]
class GetAttributes
{
static void Main(string[] args)
{
Type attributeType = typeof(MyAttribute);
Type thisClass = typeof(GetAttributes); //使用IsDefined方法
bool defined = Attribute.IsDefined(
thisClass,
attributeType);
Console.WriteLine(
"GetAttributes类型是否申明了MyAttribute特性:{0}",
defined.ToString()); //使用Attribute.GetCustomAttribute方法
Attribute att = Attribute.GetCustomAttribute(
thisClass,
attributeType);
if (att != null)
{
Console.WriteLine(
"GetAttributes类型申明了MyAttribute特性。");
Console.WriteLine("名字为:{0}",
((MyAttribute)att).Name);
} //使用Attribute.GetCustomAttributes方法
Attribute[] atts = Attribute.GetCustomAttributes(
thisClass,
attributeType);
if (atts.Length > )
{
Console.WriteLine(
"GetAttributes类型申明了MyAttribute特性。");
Console.WriteLine("名字为:{0}",
((MyAttribute)atts[]).Name);
} //使用System.Reflection.CustomAttributeData类型
IList<CustomAttributeData> list =
CustomAttributeData.GetCustomAttributes(thisClass);
if (list.Count > )
{
Console.WriteLine(
"GetAttributes类型申明了MyAttribute特性。");
//注意这里可以对特性进行分析,但不能得到其实例
CustomAttributeData attdata = list[];
Console.WriteLine("特性的名字是:{0}",
attdata.Constructor.DeclaringType.Name);
Console.WriteLine("特性的构造方法有{0}个参数。",
attdata.ConstructorArguments.Count);
}
Console.Read();
}
} /// <summary>
/// 一个简单的特性
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public sealed class MyAttribute : Attribute
{
private String _name;
public MyAttribute(String s)
{
_name = s;
}
public String Name
{
get
{
return _name;
}
}
}

输出:

GetAttributes类型是否申明了MyAttribute特性:True
GetAttributes类型申明了MyAttribute特性。
名字为:GetAttributes
GetAttributes类型申明了MyAttribute特性。
名字为:GetAttributes
GetAttributes类型申明了MyAttribute特性。
特性的名字是:MyAttribute
特性的构造方法有1个参数。

4 一个元素是否可以重复申明同一个特性

当一个特性申明了AttributeUsage特性并且显示地将AllowMultiple属性设置为true时,该特性就可以在同一元素上多次申明,否则的话编译器将被报错。

示例:

    [My("Class1")]
[My("Class2")]
[My("Class1")]
class AllowMultiple
{
static void Main(string[] args)
{
}
} /// <summary>
/// 使用AttributeUsage限定使用范围
/// 并且允许在同一元素上多次申明
/// </summary>
[AttributeUsage(AttributeTargets.Class,AllowMultiple=true)]
class MyAttribute : Attribute
{
private String _s; public MyAttribute(String s)
{
_s = s;
}
}

转载请注明出处:

作者:JesseLZJ
出处:http://jesselzj.cnblogs.com