(二)自定义特性

使自定义特性非常强大的因素时使用反射,代码可以读取这些元数据,使用它们在运行期间作出决策。

 

1、编写自定义特性

定义一个FieldName特性:

复制代码
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class FieldNameAttribute : Attribute
{
    private string name;
    public FieldNameAttribute(string name)
    {
        this.name = name;
    }
}
复制代码

 

(1)AttributeUsage特性

特性类本身用一个特性——System.AttributeUsage特性来标记。AttributeUsage第一个参数用于标识自定义特性可以应用到那些类型的程序元素上,其类型是枚举类型AttrubuteTargets。

当应用类型超过1个时,可以用OR运算符连接:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
AllowMultiple属性用于指定该特性是否可以多次应用于同一项上,当设置为false,以下编码会报错:
[FieldName("我的属性1")]
[FieldName("我的属性2")]
public int MyProperty { get; set; }
Inherited属性用于指示使用该特性的类或类成员能否由派生类或重写成员继承。

 

(2)指定特性参数

编译器会检查传递给特性的参数,并查找该特性中带这些参数的构造函数。一半仅提供一个构造函数,使用属性来定义任何其他可选参数。

 

(3)指定特性的可选参数

另一种语法,可把可选参数添加到特性中。这种语法指定可选参数的名称和值,它通过特性类中的公共属性或字段起作用。例如上述代码中AttributeUsage特性使用的AllowMultiple和Inherited就是使用的这种语法。

 

(三)反射

通过System.Type类可以访问关于任何数据类型的信息。System.Reflection.Assembly类可以用于访问给定程序集的相关信息,或者把这个程序集加载到程序中。

 

1、System.Type类

Type有与每种数据类型对应的派生类。获取指定任何给定类型的Type引用有3中常用方式:

使用C#的typeof运算符:

Type type = typeof(double);

使用GetType()方法(所有的类都会从System.Object继承这个方法):

double d = 10.0;
Type type = d.GetType();

使用Type类的静态方法GetType():

Type type = Type.GetType("System.Double");

 

(1)Type的属性

复制代码
 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         Type intType = typeof(int);
 6         Console.WriteLine("当前类型的类型名:"+intType.Name);
 7         Console.WriteLine("当前类型的类型完全限定名:" + intType.FullName);
 8         Console.WriteLine("当前类型的名称空间名:" + intType.Namespace);
 9         Console.WriteLine("当前类型的直接基类名:" + intType.BaseType);
10         Console.WriteLine("当前类型的.NET运行库中映射到的类型:" + intType.UnderlyingSystemType);
11         Console.WriteLine("是否为数组的:" + intType.IsArray);
12         Console.WriteLine("是否为值类型:" + intType.IsValueType);
13     }
14 }
15 public class MyBaseClass { }
16 public class MyClass : MyBaseClass { }
复制代码

运行以上代码,结果如下:

 

还有很多IsXXX来判断是否为某种类型。

 

(2)方法

System.Type类的大多数方法都用于获取对应数据类型的成员信息:构造函数、属性、方法和事件。后缀加‘s’的表示获取当前数据类型中所有的成员相关信息,不加则只获取数据类型中一个成员的相关信息。

Type intType = typeof(int);
var method = intType.GetMethod("GetHashCode");
var methods = intType.GetMethods();
foreach (var item in methods)
{}

System.Type类还包含有GetConstructor()方法和GetConstructors()等