C Sharp(十八)
發佈於 2018-12-10
这一篇,我们讲讲 C# 中非常重要的概念 —— 反射和特性。
很多程序语言中有元数据(matedata)的概念,其实元数据就是描述数据的数据。 一个运行的程序查看本身元数据或其他程序元数据的行为就叫做反射(reflection)。 要使用反射,我们必须引入 System.Reflection 命名空间。
BCL 声明了一个 Type 的抽象类,他被设计用来包含类型的特性。使用这个类的对象可以让我们获得程序使用的类型信息。 我们需要了解的是:
我们可以从 Type 类型的实例获取几乎所有关于类型的信息,Type 类有很多有用的成员,如:
我们可以使用 GetType 方法和 typeof 运算符获取 Type 对象。
using System.Reflection; Type t1 = myInstance.GetType(); Type t2 = typeof (DerivedClass); |
---|
特性(attribute)是一种允许我们向程序集添加元数据的语言结构。 按照惯例,特性以 Pascal 命名法,并以 Attribute 为后缀命名。当应用特性时,可以不加 Attribute 后缀。 应用特性要被方括号包裹,其中是特性名和参数列表。
[Serializable] public class MyClass { } [MyAttribute("Simple String")] public class MyOtherClas } |
---|
我们可以使用 Obsolete 特性标注方法过期:
[Obsolete("Use Method SuperPrint")] public void Print() { } |
---|
我们依旧可以使用过期方法,可以成功编译并执行,但是编译器会报警告。我们可以使用第二个布尔参数,使得编译错误。
[Obsolete("Use Method SuperPrint", true)] //调用会发生编译错误 public void Print() { } |
---|
Conditional 特性允许我们包含或排斥特定方法的所有调用。 如果定义了编译符号参数,则标记为 Conditional 特性的方法与普通方法一样,如果未定义编译符号,则所有的 Conditional 方法都不会调用:
[Conditional("DoTrace")] public void TraceMessage(string str) { Console.WriteLine(str); } |
---|
ASP.Net MVC 有很多重要的特性,我们会在学习 MVC 时再具体学习。
我们可以为单个结构应用多个特性,可以使用多层结构,也可以使用逗号分隔:
[Serializable] [MyAttribute("Simple String")] [Serializable, MyAttribute("Simple String")] |
---|
除了类,特性还可以应用于字段,属性和方法等。
所有的特性要派生自 System.Attribute。 要声明一个自定义特性:
public sealed class MyAttribute : System.Attribute { } |
---|
注意: 特性类的成员只能是:
每个特性至少有一个公共构造函数。我们在应用特性传入参数列表时,其实是在使用不同的构造函数。 关于特性构造函数: