【问题标题】:c# load inherited class from external dll in runtimec#在运行时从外部dll加载继承的类
【发布时间】:2019-05-15 17:42:49
【问题描述】:

atm 我正在“玩”一些 C# 可以做的事情——只是想知道它是如何工作的。 现在我有了在运行时从 dll 中加载一个类的想法,该类从我的原始程序中扩展了一个类。示例:

// My class in the dll.
namespace MyDll
{
  public class MyClassInDll : MyClass
  {
    public MyClassInDll(int num) : base(num)
    {
      // May contain more code :)
    }
  }
}

// My abstract class which is inherited in the dll.
namespace MyProgram
{  
  public class MyClass
  {
    private int num;

    public MyClass(int numToUse)
    {
      num = numToUse;
    }

    public void WriteTheNumber()
    {
      Console.WriteLine(num);
    }
  }
}

// My mainfile.
namespace MyProgram
{  
  public class Program
  {
    public void Main(String[] args)
    {
      // Load the DLL
      Assembly dll = Assembly.LoadFile("myDll.dll");

      // Create an instance of MyClassInDll stored as MyClass.
      MyClass myclass = ? // I dont know what to enter here :(

      // Call the function my program knows from MyClass
      myclass.WriteTheNumber(); // this should write the in the constructor passed integer to the console.
    }
  }
}

所以这是我的问题:

  • 最重要的是:创建实例需要做什么? (构造函数需要传参)
  • 我如何检查它是否成功(或者更好的是哪些异常意味着什么?)
  • 什么(其他)可能出错(找不到 dll,dll 不包含类,dll 中的类不扩展 MyClass,MyClassInDll 的构造函数与假设不同,MyClass 的方法和属性与使用的 MyClass 版本不同在 dll 中),有什么我可以做的吗?
  • 方法调用是否在 dll 中使用最终被覆盖的方法? (应该,但我不确定)

我真的希望你能帮我解决这个问题,我在 Google 上找到的只是在外部 dll 中的类中运行单个方法(或者我太愚蠢而看不到答案),但对继承的类一无所知。

谢谢!

【问题讨论】:

    标签: c# dll runtime .net-assembly


    【解决方案1】:

    首先你定义MyClass的方式不是抽象的,如果你需要它是一个抽象类那么你需要添加abstract修饰符关键字,考虑到这一点我会继续回答,好像MyClass是一个具体的类

    最重要的是:创建实例需要做什么? (构造函数需要传参数)

    是的,MyClass 的构造函数需要一个参数,准确地说是整数,所以你需要这样写:

    MyClass myclass = new MyClass(1);
    

    我如何检查它是否成功(或者更好的是哪些异常 什么意思?)

    如果您是说从加载 dll 开始,我可以告诉您有一种更好的方法可以将 dll 添加到您的项目中,将其添加为参考https://docs.microsoft.com/en-us/visualstudio/ide/managing-references-in-a-project?view=vs-2019

    什么(其他)可能出错(找不到 dll,dll 不包含 类,dll 中的类不扩展 MyClass,MyClassInDll 有一个 不同于假设的构造函数,MyClass 有不同的方法和 属性比在 dll 中使用的 MyClass 的版本)和 有什么我可以做的吗?

    你不能拥有两个具有不同方法和属性的 MyClass,你应该只拥有一个并从两个项目(你的 dll 和你的 main 方法)中使用那个。

    方法调用是否在 dll 中使用最终被覆盖的方法? (应该 但我不确定)

    如果您将方法标记为虚拟方法,则只能覆盖方法,但我认为这个问题是因为您使用了 2 个 MyClass 类,正如我之前所说的那样是一个错误。

    我希望这个,我很清楚,但如果您需要进一步的帮助,请发表评论。

    【讨论】:

    • 1) 我想动态加载它,因为我想测试类似于 Minecraft 中的插件系统,您只需将 .jar 放在插件文件夹中并在文件中写入扩展 JavaPlugin 类的类。在启动时,游戏只是找到 jar 并在其中加载类。 2) 我知道我可以使用 MyClass myclass= new MyClass(1);但我想要 MyClass myclas = new MyClassInDll(1); :) 3) 我的意思是用于编译 dll 的 MyClass 比较旧,并且有不同的方法或不同的参数。
    • 是的,我知道我只能覆盖虚拟方法,但我的意思是如果我有一个可以覆盖的方法:)
    • 1) 然后你应该在 try catch 块中加载它,你应该在 mdsn 上寻找 LoadFile 方法的错误。 2)您应该查看此网页,了解如何通过反射docs.microsoft.com/en-us/dotnet/api/… 动态使用 dll 3)正如我所说,您应该只有 1 个 MyClass,并且必须在那个地方进行更新,这样您就不会遇到此类问题。 4) 如果你将一个方法标记为虚拟方法,并且你创建了一个继承自该类的类,你将能够覆盖这些方法。
    • 所以我尝试了一下,它可以工作,但只是在构造函数中没有参数。如何将参数传递给构造函数?我发现了这个: CreateInstance(String, Boolean, BindingFlags, Binder, Object[], CultureInfo, Object[]) 但我不知道 Binder、BindingFlags 或 activationAttributes 所以我不知道如何使用这个方法。你能给我一个“正常”使用的例子吗?喜欢CreateInstance("MyDll.MyClassInDll", true, ?, ?, myArgsAsObjectArray, null, ?);?这是我完成这项工作所需的最后一件事。
    • 您可以将 null 传递给所有这些东西,binder 和属性 binder 用于指定由于使用反射而要如何执行方法的搜索,最后一个属性我不确定是什么用于但我看到它不应该在新的实现中使用,所以也尝试将它归零
    猜你喜欢
    • 2013-03-13
    • 1970-01-01
    • 2012-04-11
    • 2013-08-24
    • 2013-09-09
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2017-07-08
    相关资源
    最近更新 更多