反射提供了封装程序集、模块和类型的对象(Type类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。

使用场景#

  • 需要访问程序元数据的特性
  • 检查和实例化程序集中的类型
  • 在运行时构建新类型。使用 System.Reflection.Emit 中的类
  • 执行后期绑定,访问在运行时创建的类型的方法

反射用途#

类型作用
Assembly定义和加载程序集,加载程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例
Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法
ConstructorInfo了解构造器的名称、参数、访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数
MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法
FieldInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值
EventInfo了解事件的名称、事件处理程序数据类型、自定义特性、声明类型和反射类型等,并添加或移除事件处理程序
PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,并获取或设置属性值
ParameterInfo了解参数的名称、数据类型、参数是输入参数还是输出参数等,以及参数在方法签名中的位置等

反射用到的命名空间#

  • System.Reflection
  • System.Type
  • System.Reflection.Assembly

反射用到的主要类#

  • System.Type :通过这个类可以访问任何给定数据类型的信息
  • System.Reflection.Assembly:  可以用于访问给定程序集的信息,或者把这个程序集加载到程序中

System.Type#

一个抽象的基类。Type 有与每种数据类型对应的派生类,使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。

获取给定类型 Type 值#

typeof 运算符

Type t = typeof(string);

对象的GetType()方法

string s = "guo";
Type t = s.GetType();

Type类的静态方法GetType()

Type t = Type.GetType("System.String");

Type 属性#

属性描述
Name数据类型名
FullName数据类型的完全限定名(包括命名空间名)
Namespace定义数据类型的命名空间名
IsAbstract指示该类型是否是抽象类型
IsArray指示该类型是否是数组
IsClass指示该类型是否是类
IsEnum指示该类型是否是枚举
IsInterface指示该类型是否是接口
IsPublic指示该类型是否是公有的
IsSealed指示该类型是否是密封类
IsValueType指示该类型是否是值类型

Type 方法#

方法名称描述
GetConstructor(), GetConstructors()返回ConstructorInfo类型,用于取得该类的构造函数的信息
GetEvent(), GetEvents()返回EventInfo类型,用于取得该类的事件的信息
GetField(), GetFields()返回FieldInfo类型,用于取得该类的字段(成员变量)的信息
GetInterface(), GetInterfaces()返回InterfaceInfo类型,用于取得该类实现的接口的信息
GetMember(), GetMembers()返回MemberInfo类型,用于取得该类的所有成员的信息
GetMethod(), GetMethods()返回MethodInfo类型,用于取得该类的方法的信息
GetProperty(), GetProperties()返回PropertyInfo类型,用于取得该类的属性的信息

可以调用这些成员,其方式是调用 TypeInvokeMember() 方法,或者调用 MethodInfo , PropertyInfo 和其他类的 Invoke() 方法。

public class ReflectClass
{
    public string Address;

    public int Age { get; set; }

    public string Sex { get; set; }

    public string Name { get; set; }

    public ReflectClass() { }

    public ReflectClass(string name)
        {
            this.Name = name;
        }

    public ReflectClass(string name, string sex)
        {
            this.Name = name;
            this.Sex = sex;
        }

    public void Show()
        {
            Console.WriteLine("姓名:" + Name + "\n" + "年龄:" + Age + "\n" + "性别:" + Sex);
        }
}

获取所有构造函数#

 [TestMethod]
 public void GetConstructors()
 {
     Type t = new ReflectClass().GetType();
     // 获取类的所有构造函数
     ConstructorInfo[] constructorInfos = t.GetConstructors();
     foreach (ConstructorInfo ci in constructorInfos)
     {
         // 获取每个构造函数的参数
         ParameterInfo[] parameterInfos = ci.GetParameters();
         foreach (ParameterInfo p in parameterInfos)
         {
             Console.WriteLine(p.ParameterType.ToString() + "\n" + p.Name + "\n");
         }
     }
     Assert.IsTrue(constructorInfos.Length > 0);
 }

动态创建对象#

[TestMethod]
public void DynamicCreateObject()
{
    Type t = typeof(ReflectClass);
    Type[] pt = new Type[2];
    pt[0] = typeof(string);
    pt[1] = typeof(string);
    //根据参数类型获取构造函数
    ConstructorInfo ci = t.GetConstructor(pt);
    //构造Object数组,作为构造函数的输入参数
    object[] obj = new object[2] { "wang", "男" };
    //调用构造函数生成对象
    object @object = ci.Invoke(obj);
    //调用生成的对象的方法测试是否对象生成成功
    ((ReflectClass)@object).Show();
    Assert.IsTrue(true);
}

Activator 动态创建对象#

[TestMethod]
public void ActivatorDynamicCreateObject()
{
    Type t = typeof(ReflectClass);
    object[] obj = new object[2] { "wang", "男" };
    //用Activator的CreateInstance静态方法,生成新对象
    object @object = Activator.CreateInstance(t, obj);
    ((ReflectClass)@object).Show();
    Assert.IsTrue(true);
}

获取类中 Public 属性#

[TestMethod]
public void GetProperties()
{
    Type t = new ReflectClass().GetType();
    PropertyInfo[] propertyInfos = t.GetProperties();
    foreach (PropertyInfo p in propertyInfos)
    {
        Console.WriteLine(p.Name);
    }
    Assert.IsTrue(true);
}

获取类 Public 方法#

[TestMethod]
public void GetPublicMethod()
{
    Type t = new ReflectClass().GetType();
    MethodInfo[] mi = t.GetMethods();
    foreach (MethodInfo method in mi)
    {
        Console.WriteLine(method.ReturnType + "|" + method.Name);
    }
    Assert.IsTrue(true);
}

获取类中 Public 字段#

[TestMethod]
public void GetField()
{
    Type t = new ReflectClass().GetType();
    FieldInfo[] fieldInfos = t.GetFields();
    foreach (FieldInfo fieldInfo in fieldInfos)
    {
        Console.WriteLine(fieldInfo.Name);
    }
    Assert.IsTrue(true);
}
[TestMethod]
public void Example_01()
{
    ReflectClass rc = new ReflectClass();
    Type t = rc.GetType();
    object obj = Activator.CreateInstance(t);

    FieldInfo address = t.GetField("Address");
    address.SetValue(obj, "Beijing");

    PropertyInfo name = t.GetProperty("Name");
    name.SetValue(obj, "wang", null);

    PropertyInfo age = t.GetProperty("Age");
    age.SetValue(obj, 20, null);

    MethodInfo method = t.GetMethod("Show");
    method.Invoke(obj, null);

    Console.WriteLine("Address为:" + ((ReflectClass)obj).Address);
    Assert.IsTrue(true);
}

Assembly#

GetAssembly#

[TestMethod]
public void GetAssembly()
{
    // 通过程序集名称返回Assembly对象
    Assembly assembly = Assembly.Load("CodeSnippet");

    // 通过Assembly获取程序集中类(参数必须是类的全名)
    Type type = assembly.GetType("CodeSnippet.Csharp.ReflectClass");
    Assert.IsNotNull(type);

    // 通过Assembly获取程序集中所有的类
    Type[] types = assembly.GetTypes();
    Assert.IsNotNull(types);

    // 通过DLL文件名称返回Assembly对象
warning disable S3885 // "Assembly.Load" should be used
    Assembly assembly2 = Assembly.LoadFrom("CodeSnippet.dll");
warning restore S3885 // "Assembly.Load" should be used

    // 通过Assembly获取程序集中类(参数必须是类的全名)
    Type type2 = assembly2.GetType("CodeSnippet.Csharp.ReflectClass");
    Assert.IsNotNull(type2);

    // 通过Assembly获取程序集中所有的类
    Type[] types2 = assembly2.GetTypes();
    Assert.IsNotNull(types2);
}

通过程序集名称反射#

[TestMethod]
public void Example_02()
{
    Assembly assembly = Assembly.Load("CodeSnippet");
    //参数必须是类的全名
    Type t = assembly.GetType("CodeSnippet.Csharp.ReflectClass");
    object o = Activator.CreateInstance(t, "男");
    MethodInfo mi = t.GetMethod("Show");
    mi.Invoke(o, null);
    Assert.IsNotNull(o);
}

通过DLL文件反射类型#

[TestMethod]
public void Example_03()
{
warning disable S3885 // "Assembly.Load" should be used
    Assembly assembly = Assembly.LoadFrom("CodeSnippet.dll");
warning restore S3885 // "Assembly.Load" should be used
    Type[] types = assembly.GetTypes();
    foreach (Type t in types)
    {
        if (t.FullName == "CodeSnippet.Csharp.ReflectClass")
        {
            object o = Activator.CreateInstance(t);
            Assert.IsNotNull(o);
        }
    }
}

BindingFlags#

//     Specifies flags that control binding and the way in which the search for members
//     and types is conducted by reflection.