下面是关于“C#反射应用实例”的完整攻略。
什么是C#反射?
C#反射是让程序在运行时动态获取类型信息的功能。通过C#反射,可以在不知道类型名称的情况下获取相应的类型,并对类型的成员进行操作。C#反射提供了一种动态获取类型信息的方式,使得程序具有更高的灵活性和可扩展性。
C#反射的基本用法
获取类型对象
使用反射获取类型信息的第一步是获取类型对象。可以通过Type.GetType()
、typeof()
或者object.GetType()
等方法获取类型对象。例如,下面的代码演示了如何获取List<int>
的类型对象:
Type type = typeof(List<int>);
获取类型的成员
获取类型的成员可以使用Type.GetMembers()
或者Type.GetMethods()
等方法。通过这些方法可以获取该类型所包含的所有成员,比如属性、方法、字段、事件等。下面的代码演示了如何获取List<int>
类型的所有方法:
MethodInfo[] methods = typeof(List<int>).GetMethods();
foreach (MethodInfo method in methods)
{
Console.WriteLine(method.Name);
}
调用对象的方法
调用对象的方法需要先获取该方法的MethodInfo
对象,然后使用MethodInfo.Invoke()
方法执行方法。下面的代码演示了如何创建一个字符串对象并调用其ToUpper方法:
string myString = "hello world";
MethodInfo toUpperMethod = typeof(string).GetMethod("ToUpper", new Type[] { });
string upperCaseString = (string)toUpperMethod.Invoke(myString, null);
Console.WriteLine(upperCaseString); // HELLO WORLD
修改或设置对象的属性值
修改对象的属性值需要先获取该属性的PropertyInfo
对象,然后使用PropertyInfo.SetValue()
方法设置属性值。下面的代码演示了如何创建一个Person对象并修改其名字属性:
class Person
{
public string Name { get; set; }
}
Person p = new Person();
PropertyInfo nameProperty = typeof(Person).GetProperty("Name");
nameProperty.SetValue(p, "Tom");
Console.WriteLine(p.Name); // Tom
运行时创建对象
运行时创建对象可以使用Activator.CreateInstance()
方法。该方法通过参数指定对象的类型,然后返回该类型的一个实例。下面的代码演示了如何创建一个StringBuilder对象并往其中添加一些文本:
object myStringBuilder = Activator.CreateInstance(typeof(StringBuilder));
MethodInfo appendMethod = typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(string) });
appendMethod.Invoke(myStringBuilder, new object[] { "Hello " });
appendMethod.Invoke(myStringBuilder, new object[] { "World" });
Console.WriteLine(myStringBuilder.ToString()); // Hello World
示例说明
下面给出两个C#反射的示例说明:
示例一:动态生成类
动态生成类可以使用System.Reflection.Emit
命名空间中的类型。下面的代码演示了如何使用AssemblyBuilder
动态生成一个简单的类:
using System.Reflection;
using System.Reflection.Emit;
class Program
{
static void Main(string[] args)
{
AssemblyName asmName = new AssemblyName("MyAssembly");
AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule("MyModule", "MyAssembly.dll");
TypeBuilder typeBuilder = moduleBuilder.DefineType("MyClass");
MethodBuilder methodBuilder =
typeBuilder.DefineMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Static);
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldstr, "Hello World");
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
ilGenerator.Emit(OpCodes.Ret);
Type myType = typeBuilder.CreateType();
MethodInfo myMethod = myType.GetMethod("MyMethod", BindingFlags.Public | BindingFlags.Static);
myMethod.Invoke(null, null);
}
}
示例二:使用特性获取方法的调用信息
下面的代码演示了如何使用特性获取方法的调用信息:
using System;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CallInfoAttribute : Attribute
{
private string className;
private string methodName;
public CallInfoAttribute(string className, string methodName)
{
this.className = className;
this.methodName = methodName;
}
public string ClassName
{
get { return className; }
}
public string MethodName
{
get { return methodName; }
}
}
class Program
{
[CallInfo("Program", "Main")]
static void MyMethod()
{
CallInfoAttribute attr = (CallInfoAttribute)Attribute.GetCustomAttribute(
typeof(Program).GetMethod("MyMethod"), typeof(CallInfoAttribute));
Console.WriteLine("Class: {0}, Method: {1}", attr.ClassName, attr.MethodName);
}
static void Main(string[] args)
{
MyMethod();
}
}
以上就是关于“C#反射应用实例”的完整攻略,希望对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#反射应用实例 - Python技术站