C#反射机制介绍
C#中的反射机制是一种强大的工具,可以在程序运行时动态地获取类型信息、创建对象以及调用对象的方法和属性等操作,这使得我们可以编写更加灵活、可扩展的程序。
获取类型信息
在C#中,使用Type
类来获取类型信息。通常可以使用typeof
运算符获取类型的信息,例如:
Type t = typeof(string);
也可以使用对象的GetType
方法来获取其对应的类型信息,例如:
string s = "Hello world!";
Type t = s.GetType();
使用Type
类可以获取类型的名称、命名空间、构造函数、属性、字段等信息。
创建对象
在C#中,使用Activator
类来创建对象。通过Activator
类,可以调用对象的无参构造函数来创建一个新的实例,例如:
Type t = typeof(MyClass);
object obj = Activator.CreateInstance(t);
其中,MyClass
为要创建对象的类型。
如果要创建带有参数的对象,则需要使用Activator
类的重载方法,例如:
Type t = typeof(MyClass);
object[] args = new object[]{"hello", 123};
object obj = Activator.CreateInstance(t, args);
其中,参数"hello"
和123
为要传递给构造函数的参数值。
调用方法和属性
在C#中,使用MethodInfo
类来获取方法的信息。可以通过Type
类的GetMethod
方法来获取一个方法的信息,例如:
Type t = typeof(MyClass);
MethodInfo mi = t.GetMethod("MyMethod");
其中,"MyMethod"
为要获取的方法的名称。
通过MethodInfo
类,可以调用该方法,并传递参数值,例如:
Type t = typeof(MyClass);
MethodInfo mi = t.GetMethod("MyMethod");
object obj = Activator.CreateInstance(t);
object[] args = new object[]{"hello", 123};
object result = mi.Invoke(obj, args);
其中,"hello"
和123
为要传递给方法的参数值,result
为该方法返回的结果。
在C#中,使用PropertyInfo
类来获取属性的信息。可以通过Type
类的GetProperty
方法来获取一个属性的信息,例如:
Type t = typeof(MyClass);
PropertyInfo pi = t.GetProperty("MyProperty");
其中,"MyProperty"
为要获取的属性的名称。
通过PropertyInfo
类,可以获取该属性的值或设置该属性的值,例如:
Type t = typeof(MyClass);
PropertyInfo pi = t.GetProperty("MyProperty");
object obj = Activator.CreateInstance(t);
// 获取属性值
object value = pi.GetValue(obj);
// 设置属性值
pi.SetValue(obj, newValue);
其中,newValue
为要设置的属性值。
示例说明
示例1:动态创建类型
下面展示如何使用反射机制来动态地创建一个类:
using System.Reflection;
using System.Reflection.Emit;
public class MyClassBuilder
{
public static Type CreateMyClass()
{
AssemblyName assemblyName = new AssemblyName(Guid.NewGuid().ToString());
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(Guid.NewGuid().ToString());
TypeBuilder typeBuilder = moduleBuilder.DefineType("MyClass", TypeAttributes.Public);
MethodBuilder methodBuilder = typeBuilder.DefineMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int) });
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_I4_S, 2);
ilGenerator.Emit(OpCodes.Mul);
ilGenerator.Emit(OpCodes.Ret);
return typeBuilder.CreateType();
}
}
使用上述代码,我们就可以动态地创建一个名为MyClass
的类,并具有一个名为MyMethod
的公共静态方法,该方法接受一个int
类型的参数,并返回该参数的两倍。例如:
Type t = MyClassBuilder.CreateMyClass();
MethodInfo mi = t.GetMethod("MyMethod");
int result = (int)mi.Invoke(null, new object[]{2});
Console.WriteLine(result); // 输出:4
示例2:通过配置文件来调用对象方法
下面展示如何使用反射机制来实现通过配置文件来调用对象的方法。假设我们有一个类MyClass
,该类具有一个名为MyMethod
的公共方法。我们可以在配置文件中指定要调用该方法的对象类型、方法名称以及参数,然后在程序运行时根据配置文件中的信息来动态地调用该方法。
首先,定义配置文件的格式如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<MyClass>
<Method name="MyMethod" arg1="hello" arg2="123" />
</MyClass>
</configuration>
接下来,我们可以编写如下代码来读取配置文件中的信息,并调用相应的对象方法:
using System.Configuration;
public static class AppConfigDemo
{
public static void Run()
{
string typeName = ConfigurationManager.AppSettings["typeName"];
string methodName = ConfigurationManager.AppSettings["methodName"];
string arg1 = ConfigurationManager.AppSettings["arg1"];
string arg2 = ConfigurationManager.AppSettings["arg2"];
Type t = Type.GetType(typeName);
object obj = Activator.CreateInstance(t);
MethodInfo mi = t.GetMethod(methodName);
object[] args = new object[] { arg1, int.Parse(arg2) };
object result = mi.Invoke(obj, args);
Console.WriteLine("Result: " + result);
}
}
使用上述代码,我们就可以通过配置文件来调用对象的方法。例如,假设我们要调用MyClass
的MyMethod
方法,可以配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="typeName" value="MyClass" />
<add key="methodName" value="MyMethod" />
<add key="arg1" value="hello" />
<add key="arg2" value="123" />
</appSettings>
</configuration>
然后,在程序中调用AppConfigDemo.Run()
方法即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#反射机制介绍 - Python技术站