主要内容

  • 反射和特性-Type类
  • 反射和特性-Assembly程序集类
  • Obsolete特性
  • Contional特性
  • 调用者信息特性
  • DebuggerStepThrough特性
  • 创建自定义特性

反射和特性-Type类

图示 元数据与反射定义
图示 Type说明
图示 Type的部分成员

图示 Type对象的获取

MyClass类

namespace _014_反射和特性 {
class MyClass
{
private int id;
private int age;
public int number;
public string Name { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }

public void Test1() {

}
public void Test2() {

}
}
}

Main

using System;
using System.Reflection;

namespace _014_反射和特性
{
class Program
{
static void Main(string[] args)
{
//每一个类对应一个type对象,这个type对象存储了这个类有哪些方法跟哪些数据哪些成员
//一个类中的数据是存储在对象中的,但是type对象只存储类的成员
MyClass my = new MyClass();
//通过对象获取这个对象所属类的Type对象
Type type = my.GetType();
//获取类的名字
Console.WriteLine(type.Name);
//获取所在的命名空间
Console.WriteLine(type.Namespace);
Console.WriteLine(type.Assembly);
//只能获取public 栏位
FieldInfo[] array = type.GetFields();
foreach (FieldInfo info in array)
{
Console.Write(info.Name + " ");
}
PropertyInfo[] array2 = type.GetProperties();
foreach (PropertyInfo info in array2)
{
Console.Write(info.Name + " ");
}
MethodInfo[] array3 = type.GetMethods();
foreach (MethodInfo info in array3)
{
Console.Write(info.Name + " ");
}
//通过type对象可以获取它对应的类的所有成员(public)
}
}
}

图示 运行结果

反射和特性-Assembly程序集类

using System;
using System.Reflection;

namespace _014_反射和特性
{
class Program {
static void Main(string[] args) {
MyClass my = new MyClass();
//通过类的type对象获取它所在的程序集Assembly
Assembly assem = my.GetType().Assembly;
Console.WriteLine(assem.FullName);
//输出程序集中的类
Type[] types = assem.GetTypes();
foreach (var type in types)
{
Console.WriteLine(type);
}
Console.ReadKey();
}
}
}

图示 运行效果

补充

图示 Assembly类

图示 Assembly对象的使用

Obsolete特性

图示 特性的定义
图示 特性的创建与使用
图示 应用特性
图示 Obsolete特性

图示 运行效果

Conditional特性

图示 Conditional特性的定义

//定义一个宏,才可以执行调用的方法
#define IsTest

using System;
using System.Diagnostics;

namespace _015_特性
{
class Program {
//会编译到程序集当中,但不会被调用
[Conditional("IsTest")]
static void Test1() {
Console.WriteLine("test1");
}
static void Test2() {
Console.WriteLine("test2");
}
static void Main(string[] args) {
Test1();
Test2();
Test1();
Test2();
Console.ReadKey();
}
}
}

图示 运行结果

//定义一个宏,才可以执行调用的方法
//#define IsTest
......

图示 运行结果

调用者信息特性

图示 调用者信息说明

using System;
using System.Runtime.CompilerServices;

namespace _015_特性
{
class Program
{
static void PrintOut(string str, [CallerFilePath] string fileName = "",
[CallerLineNumber] int lineNumber = 0, [CallerMemberName] string methodName = "")
{
Console.WriteLine(str);
Console.WriteLine(fileName);
Console.WriteLine(lineNumber);
Console.WriteLine(methodName);
}
static void Main(string[] args)
{
PrintOut("123");
}
}
}

图示 运行结果

DebuggerStepThrough特性

我们在单步调试代码的时候,常常希望调试器不要进入某些方法。我们只想执行该方法,然后继续调试下一行。DebuggerStepThrough特性告诉调试器在执行目标代码时不要进入该方法调试。有些方法小并且毫无疑问是正确的,在调试时对其反复单步调试只能徒增烦恼。要小心使用该特性,不要排除了可能出现bug的代码。

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace _015_特性
{
class Program {
//可以跳过debugger 的单步调试 不让进入该方法
//(当我们确定这个方法没有任何错误的时候,可以使用这个)
[DebuggerStepThrough]
static void PrintOut(string str,[CallerFilePath] string fileName="",
[CallerLineNumber] int lineNumber=0,[CallerMemberName] string methodName ="")
{
Console.WriteLine(str);
Console.WriteLine(fileName);
Console.WriteLine(lineNumber);
Console.WriteLine(methodName);
}
static void Main(string[] args) {
PrintOut("123");
Console.ReadKey();
}
}
}

不添加DebuggerStepThrough特性

图示 运行效果

添加DebuggerStepThrough特性

图示 运行效果

创建自定义特性

图示 自定义特型说明
图示 构造函数
图示 自定义特性的一般规范
图示 限定特性的使用
图示 访问特性

MyTestAttribute类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace _015_特性 {
//1, 特性类的后缀以Attribute结尾
//2, 需要继承自System.Attribute
//3, 一般情况下声明为 sealed
//4, 一般情况下 特性类用来表示目标结构的一些状态(定义一些栏位或者属性, 一般不定义方法)
[AttributeUsage(AttributeTargets.Class)]//表示该特性类可以应用到的程序结构有哪些
sealed class MyTestAttribute : System.Attribute {
public string Description { get; set; }
public string VersionNumber { get; set; }
public int ID { get; set; }

public MyTestAttribute(string des)
{
this.Description = des;
}
}
}

Program类

using System;
namespace _015_特性
{
//通过制定属性的名字,给属性赋值,这种事命名参数
//当我们使用特性的时候,后面的Attribute不需要写
[MyTest("简单的特性类",ID = 100)]
class Program {
static void Main(string[] args) {
//通过typeof+类名也可以获取type对象
Type type = typeof (Program);
object[] array = type.GetCustomAttributes(false);
MyTestAttribute mytest = array[0] as MyTestAttribute;
Console.WriteLine(mytest.Description);
Console.WriteLine(mytest.ID);
Console.ReadKey();
}
}
}

图示 运行效果


推荐阅读:
相关文章