C#使用反射(Reflect)获取DLL文件中的类型,创建对象并调用对象的方法。

使用反射(Reflect)获取DLL文件中的类型并调用方法可以分为以下几个步骤:

1.加载DLL文件:使用Assembly.LoadFrom方法加载指定DLL文件。

   Assembly assembly = Assembly.LoadFrom("MyLibrary.dll");

2.获取类型:使用Assembly.GetType方法获取指定类型的Type对象。

   Type type = assembly.GetType("MyLibrary.MyClass");

3.创建对象:使用Activator.CreateInstance方法创建指定类型的实例。

   object instance = Activator.CreateInstance(type);

4.调用方法:使用Type.GetMethod方法获取指定方法的MethodInfo对象,然后使用MethodInfo.Invoke方法调用该方法。

   MethodInfo method = type.GetMethod("MyMethod");
   method.Invoke(instance, null);

 创建对象的两种方法:

 Activator.CreateInstance方法可以创建任意类型的对象,使用Type.GetConstructor方法获取到指定的构造函数,然后调用其Invoke方法来创建对象。

using System;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        Assembly assembly = Assembly.LoadFrom("MyLibrary.dll");
        Type type = assembly.GetType("MyLibrary.MyClass");

        // 通过 Activator.CreateInstance 方法创建有参对象
        object instance1 = Activator.CreateInstance(type, "parameter1");

        // 通过构造函数的方式创建有参对象
        ConstructorInfo constructor1 = type.GetConstructor(new Type[] { typeof(string) });
        object instance2 = constructor1.Invoke(new object[] { "parameter2" });

        // 通过 Activator.CreateInstance 方法创建无参对象
        object instance3 = Activator.CreateInstance(type);

        // 通过构造函数的方式创建无参对象
        ConstructorInfo constructor2 = type.GetConstructor(Type.EmptyTypes);
        object instance4 = constructor2.Invoke(null);

        // 调用有参方法
        MethodInfo method1WithParameters = type.GetMethod("MyMethodWithParameters");
        method1WithParameters.Invoke(instance1, new object[] { "method1 parameter" });

        // 调用无参方法
        MethodInfo method2 = type.GetMethod("MyMethod");
        method2.Invoke(instance2, null);

        // 调用有参方法
        method1WithParameters.Invoke(instance3, new object[] { "method1 parameter for instance3" });

        // 调用无参方法
        method2.Invoke(instance4, null);
    }
}

namespace MyLibrary
{
    public class MyClass
    {
        // 有参构造函数
        public MyClass(string param)
        {
            Console.WriteLine("Parameterized constructor called! Parameter: " + param);
        }

        // 无参构造函数
        public MyClass()
        {
            Console.WriteLine("Default constructor called!");
        }

        // 有参方法
        public void MyMethodWithParameters(string param)
        {
            Console.WriteLine("Method with parameters called! Parameter: " + param);
        }

        // 无参方法
        public void MyMethod()
        {
            Console.WriteLine("Method called!");
        }
    }
}

当我们使用反射实例化对象时,可以根据具体的需求选择适合的方法。

  1. Activator.CreateInstance(Type type)
    这是一个通用的实例化对象方法,可以创建任意类型的对象。我们只需要将要创建的对象的类型作为参数传递给Activator.CreateInstance方法即可。返回的是一个object类型的实例,需要进行类型转换后才能调用具体的成员。

    优点:

    • 简单方便,不需要知道具体的构造函数和参数类型。
    • 可以动态地创建对象,适用于在运行时根据条件决定要创建的对象类型的情况。

    缺点:

    • 使用反射机制,性能上可能会比直接调用构造函数的方式略慢些。
  2. Type.GetConstructor(Type[] types).Invoke(object[] parameters)
    这种方式通过构造函数来实例化对象。首先,我们需要使用Type.GetConstructor方法获取到指定的构造函数,然后调用其Invoke方法来创建对象。在调用Invoke方法时,我们需要传入一个Type[]数组作为构造函数的参数类型列表,并传入一个object[]数组作为构造函数的参数值列表。

    优点:

    • 可以精确地指定要使用的构造函数及其参数。
    • 在创建对象时可以传递参数,灵活性更高。

    缺点:

    • 需要明确知道要使用的构造函数及其参数类型。
    • 需要在代码中显式地指定构造函数的参数类型和值。

总结:

  • 如果我们需要在运行时动态地创建对象,并且不需要传递构造函数的参数,可以使用Activator.CreateInstance方法。
  • 如果我们需要精确地指定构造函数以及参数,并且能够灵活地控制对象的创建过程,可以使用Type.GetConstructorInvoke方法。

需要注意的是,反射机制在性能上可能会比直接调用构造函数的方式略慢,因此在实际开发中应根据具体情况选择合适的方式。

我们创建了一个类库项目,定义了一个类,包含了4个方法,一个带有1个参数,一个带有2个参数,一个没有参数,以及一个私有方法。然后编译生成了dll。接着,我们在另一个项目中读取MyClassLibrary.dll为字节流并加载了该dll,并调用了其中的方法。

namespace MyClassLibrary
{
public class MyClass
{
public void MethodWithOneParam(string message)
{
Console.WriteLine("MethodWithOneParam called with message: " + message);
}

    public void MethodWithTwoParams(int num1, int num2)
    {
        Console.WriteLine("MethodWithTwoParams called with nums: " + num1 + " and " + num2);
    }

    public void MethodWithoutParam()
    {
        Console.WriteLine("MethodWithoutParam called");
    }

    private void PrivateMethod()
    {
        Console.WriteLine("PrivateMethod called");
    }

    public void PublicCallPrivateMethod()
    {
        PrivateMethod();
    }
}
}

编译MyClassLibrary项目,生成MyClassLibrary.dll文件。

创建一个新的控制台应用程序项目,命名为MyConsoleApp。

在MyConsoleApp项目中,编写以下代码来加载MyClassLibrary.dll,并调用其中的方法:

using System;
using System.IO;
using System.Reflection;

namespace MyConsoleApp
{
class Program
{
static void Main(string[] args)
{
// 读取MyClassLibrary.dll为字节流
byte[] assemblyBytes = File.ReadAllBytes("MyClassLibrary.dll");


        // 加载字节流为程序集
        Assembly assembly = Assembly.Load(assemblyBytes);

        // 获取MyClass类型
        Type myClassType = assembly.GetType("MyClassLibrary.MyClass");

        // 创建MyClass实例
        object myClassInstance = Activator.CreateInstance(myClassType);

        // 调用MethodWithOneParam方法
        MethodInfo methodWithOneParam = myClassType.GetMethod("MethodWithOneParam");
        methodWithOneParam.Invoke(myClassInstance, new object[] { "Hello from method with one param" });

        // 调用MethodWithTwoParams方法
        MethodInfo methodWithTwoParams = myClassType.GetMethod("MethodWithTwoParams");
        methodWithTwoParams.Invoke(myClassInstance, new object[] { 5, 10 });

        // 调用MethodWithoutParam方法
        MethodInfo methodWithoutParam = myClassType.GetMethod("MethodWithoutParam");
        methodWithoutParam.Invoke(myClassInstance, null);

        // 调用PrivateMethod 通过PublicCallPrivateMethod
        MethodInfo publicCallPrivateMethod = myClassType.GetMethod("PublicCallPrivateMethod");
        publicCallPrivateMethod.Invoke(myClassInstance, null);
    }
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值