反射
特性
特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性:预定义特性和自定义特性。在 C# 中,通过用方括号 ([]) 将特性名称括起来,并置于应用该特性的实体的声明上方以指定特性。如下代码所示:
public class User
{
[Required(ErrorMessage = "用户Id是必填的")]
public int UserId { get; set; }
}
条件编译,如 Debug 模式
这个预定义特性标记了一个条件方法,其执行依赖于指定的预处理标识符。
它会引起方法调用的条件编译,取决于指定的值,比如 Debug
或 Trace
。例如,当调试代码时显示变量的值。
规定该特性的语法如下:
[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); // 该值指示类型是否为数组
.....
}