天天看点

【.NET】反射

什么是反射?

反射是.net的一种重要机制,通过反射在运行时获取程序(exe)或程序集(dll)中每一个类型(包含类,结构,委托,接口,枚举等)的成员和成员的信息,还可以创建这些类型的对象 。(简单的说,有了反射,你就可以通过程序和程序集获取你想要的一切信息和资源。。。)

如何使用反射?

  1. 反射的命名空间
    •  System.Reflection
    • System.Type
    • System.Reflection.Assembly
  2. 加载程序集
    • 方法1:  将dll或exe拷贝至当前项目的运行程序所在目录下,如:“Test.dll"
    •                Assembly assembly = Assembly.Load("Test");
    • 方法2:  直接加载具体路径下的程序集,如:”D:\Test\Test.dll“
    •               Assembly assembly = Assembly.LoadFrom(@"D:\Test\Test.dll");
  3. 获取类型
    • 方法1: 通过 已知的类名获取类型,如:“Test.CTest"
    •               Type type = assembly.GetType("Test.CTest");  
    • 方法 2: 通过程序集遍历所有的类型
    • foreach(var type in assembly.GetTypes())
      {
      	//代码段
      }
                 
  4. 反射创建对象(通过类型创建实例)
    •                 object obj = Activator.CreateInstance(type);
  5. 反射调用实例方法,静态方法,重载方法
    • 方法一: 通过已知方法名调用方法,如:方法“void Func()"
    •                 MethodInfo method = type.GetMethod("Func");
    •                 method.Invoke(obj, null);
    • 方法二: 遍历方法再调用 
    • foreach(var method in type.GetMethods())
      {
            method.Invoke(obj, null);  //此示例调用的是类的无参公共成员方法 
      }
                 
  6. 反射调用私有方法,泛型方法
    • 反射私有方法:
    • foreach(var method in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public |BindingFlags.Instance|BindingFlags.Static))
      {
             if (method.Name.Equals("Func1"))
             {
                   method.Invoke(obj, null);    //实例方法 需要传入实例和参数,无参可传入null
             }
             else if (method.Name.Equals("Func2"))
             {
                   method.Invoke(null, new object[] { 100 });  //类方法的调用可以不用传入实例
             }
      }
                 
    • 反射泛型方法, 如:函数签名 public void FuncGeneric<T>( T tParameter );
    if(method.Name.Equals("FuncGeneric")) 
    	{ 
        		MethodInfo methodTmp = method.MakeGenericMethod(typeof(string)); 
        		methodTmp.Invoke(obj, new object[] { "hello, kitty" }); 
    	}
               
  7. 反射字段和属性
    • 反射字段,如: 有字段 int iD, string name           
    foreach(var value in type.GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static|                               BindingFlags.Instance))
    	{
    		if(value.Name.ToString().Equals("Name"))
                    {
                          value.SetValue(null, "Xiaowangba");
                    }
                    else if(value.Name.ToString().Equals("ID"))
                    {
                         Console.WriteLine("Field ID={0}",value.GetValue(obj));  //如果是类字段 即可不用传入实例,直接传入null即可
                    }
    	}
               
    • 反射属性,如: 有属性  int  Age{set;get;}
    • foreach(var property in type.GetProperties())
      { 
      	if(property.Name.Equals("Age")) 
      	{ 
      		Console.WriteLine("Age = {0}", property.GetValue(obj)); 
      		property.SetValue(obj, 18); 
      		Console.WriteLine("After SetValue: Age = {0}", property.GetValue(obj)); 
      	} 
      }