C# 系列 -- 反射

879 阅读2分钟

反射

特性

特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。在 C# 中,通过用方括号 ([]) 将特性名称括起来,并置于应用该特性的实体的声明上方以指定特性。如下代码所示:

public class User 
{
    [Required(ErrorMessage = "用户Id是必填的")]
    public int UserId { get; set; }
}

条件编译,如 Debug 模式

这个预定义特性标记了一个条件方法,其执行依赖于指定的预处理标识符。

它会引起方法调用的条件编译,取决于指定的值,比如 DebugTrace。例如,当调试代码时显示变量的值。

规定该特性的语法如下:

[Conditional(conditionalSymbol)]

示例

namespace Malema.net
{
    public class Myclass
    {
        [Conditional("DEBUG")]
        public static void Message(string msg)
        {
            Console.WriteLine(msg);
        }
    }
    class Program
    {
        static async Task Main(string[] args)
        {
            Myclass.Message("hello");
            Console.ReadLine();
        }
    }
}

上面的代码在Debug模式下,会输出 hello。在Release模式下不会输出hello

标记程序,如过期提示

这个预定义特性标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。例如,当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个应该使用新方法,而不是旧方法的消息,来把它标记为 obsolete(过时的)。

规定该特性的语法如下:

[Obsolete(message)]
[Obsolete(message,iserror)]

其中:

  • 参数 message,是一个字符串,描述项目为什么过时以及该替代使用什么。
  • 参数 iserror,是一个布尔值。如果该值为 true,编译器应把该项目的使用当作一个错误。默认值是 false(编译器生成一个警告)。 下面的实例演示了该特性:
 [Obsolete("过期了,请使用YourClass.Abc")]
    public class Myclass
    {
        public static void Message(string msg)
        {
            Console.WriteLine(msg);
        }
    }
    class Program
    {
        static async Task Main(string[] args)
        {
            Myclass.Message("helo");
            Console.ReadLine();
        }
    }

我们会看到如下图这样的编译警告提示

反射

C# 中,查看和操作元数据就称之为反射!反射提高了程序的灵活性和扩展性。说到反射,不得不说到我们 C# 中的 System.Type 类。

获取任何类型的Type引用的常用方式有如下两种

Type type = typeof(int);

int number = 1;
Type type = number.GetType();

Type是许多反射功能的入口,它实现了很多方法和属性!属性主要是用来获取相关的各种名称的字符串,而方法主要是用来获取对应数据类型的构造函数、方法、事件等东西

static void Main(string[] args)
{
    Type type = typeof(int);

    Console.WriteLine(type.Name);   //  获取当前类型的名称
    Console.WriteLine(type.FullName);// 获取当前类型的名称包括了命名空间
    Console.WriteLine(type.IsAbstract); //判断是否是抽象的
    Console.WriteLine(type.IsValueType); // 判断是否是值类型
    Console.WriteLine(type.IsArray); // 该值指示类型是否为数组
    .....
}