C#反射机制介绍

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);
    }
}

使用上述代码,我们就可以通过配置文件来调用对象的方法。例如,假设我们要调用MyClassMyMethod方法,可以配置如下:

<?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技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • C#winform中数据库绑定DataGrid的实现

    C# WinForm中实现数据库绑定DataGrid主要分以下几步: 1. 创建数据源 首先,需要创建一个数据源来绑定DataGrid。可以使用Visual Studio自带的DataSet Designer来创建一个数据源,也可以手动创建。创建数据源主要包括以下几步: 在Solution Explorer中选择项目,右击选择“Add” -> “New…

    C# 2023年5月31日
    00
  • C#连接mariadb(MYSQL分支)代码示例分享

    下面我将为您详细讲解“C#连接mariadb(MYSQL分支)代码示例分享”的完整攻略。 一、准备工作 在连接 mariadb 前需要先安装 mariadb 的 C# 驱动,如下所示: PM> Install-Package MySql.Data 二、连接 mariadb 数据库 通过以下代码示例,我们可以使用 C# 连接 mariadb 数据库: s…

    C# 2023年6月2日
    00
  • C#如何Task执行任务,等待任务完成

    当我们需要在应用程序中执行耗时的任务时,我们可以使用Task类。下面是使用Task执行任务并等待任务完成的攻略: 创建Task任务 要创建一个Task,我们可以使用Task.Run()方法来启动一个任务。该方法接受一个委托(Delegate)类型的参数,该委托指定要在新线程上运行的代码。 例如,下面是一个简单的Task创建示例: Task task = Ta…

    C# 2023年6月6日
    00
  • C#实现窗体与子线程的交互的方法

    实现窗体与子线程的交互在C#开发中是一个比较常见的问题,这里提供一些实现交互的方法: 使用Control.Invoke方法 在C#中,使用Control.Invoke方法是实现窗体与子线程交互的方法之一。该方法可以跨线程调用控件。以下是使用Control.Invoke方法的示例代码: private void button1_Click(object sen…

    C# 2023年6月6日
    00
  • C# CheckedListBox控件的用法总结

    C# CheckedListBox控件的用法总结 简介 C# CheckedListBox控件是Windows窗体应用程序中常用的控件之一,它可以让用户在一个列表中,通过勾选方式选择其中的多个选项。本文将总结C# CheckedListBox控件的用法,包括如何进行添加、删除、修改、选中等操作,以及如何获取用户选择的内容。 创建CheckListBox控件 …

    C# 2023年6月7日
    00
  • c# WPF中的TreeView使用详解

    下面我将详细讲解“c# WPF中的TreeView使用详解”的完整攻略。该攻略将从以下几个方面进行讲解: 简介与基础概念 常用属性与方法的介绍 实战示例 简介与基础概念 TreeView是WPF中用于显示树结构的控件,常用于显示文件夹、目录等具有层级结构的数据。TreeView由节点和分支构成,每个节点可以包含零个或多个子节点,分支表示父子关系。 在Tree…

    C# 2023年5月31日
    00
  • C#从数据库读取图片并保存的两种方法

    首先我们需要了解以下两种从数据库读取图片并保存的方法: 将图片转换为二进制保存到数据库中,读取时再将二进制转换为图片; 在服务器本地保存图片,将本地图片路径保存到数据库中,读取时根据路径从本地读取图片。 下面我们逐一介绍这两种方法。 方法一:将图片转换为二进制保存到数据库中 1.1 保存图片到数据库 首先,我们需要将读取到的图片转换成二进制,然后将二进制数据…

    C# 2023年6月2日
    00
  • C#实现AddRange为数组添加多个元素的方法

    “AddRange”方法可以用于在C#数组中添加多个元素。下面是实现“AddRange”方法的步骤: 步骤1:创建一个数组 首先,你需要创建一个数组来存储要添加的元素。下面是创建一个包含3个元素的字符串数组的示例代码: string[] myArray = new string[] { "apple", "banana&quot…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部