c# - 使用反射的对象实例化适用于 VB.NET,但不适用于 C#

标签 c# .net vb.net dll system.reflection

我正在尝试从 dll 实例化一个对象而不引用它。我可以在 VB.NET 中使用 Reflection 来完成此操作,但不知道如何在 C# 中完成此操作。

在 VB.NET 中:

Public Class Form1

Dim bytes() As Byte = System.IO.File.ReadAllBytes("\\path\directory\file.dll")
Dim assmb As System.Reflection.Assembly = System.Reflection.Assembly.Load(bytes)
Dim myDllClass As Object = assmb.CreateInstance("myNamespace.myClass")

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim conStr As String = myDllClass.publicConString
    Dim dt As DataTable = myDllClass.MethodReturnsDatatable("select * from Part", conStr)
    DataGridView1.DataSource = dt

End Sub

在 C# 中:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    static byte[] bytes = System.IO.File.ReadAllBytes(@"\\path\directory\file.dll");
    static System.Reflection.Assembly assmb = System.Reflection.Assembly.Load(bytes);
    object myDllClass = assmb.CreateInstance("myNamespace.myClass");

    private void Form1_Load(object sender, EventArgs e)
    {
        string conStr = myDllClass.publicConString;
        DataTable dt = myDllClass.MethodReturnsDatatable("select * from Part", conStr);
        dataGridView1.DataSource = dt;
    }                
}

我收到这两个错误:

Error 1 'object' does not contain a definition for 'publicConString' and no extension method 'publicConString' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) C:\Users\Username\Desktop\C#\FormTest\FormTest\Form1.cs 29 34 FormTest

Error 2 'object' does not contain a definition for 'MethodReturnsDatatable' and no extension method 'MethodReturnsDatatable' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) C:\Users\Username\Desktop\C#\FormTest\FormTest\Form1.cs 30 33 FormTest

最佳答案

VB.NET 将允许您执行“后期绑定(bind)”(当未使用option strict 或通过项目属性明确允许时)。这将让运行时检查对象是否具有在调用某个方法之前。这在 C# 中也是可能的,但是您需要明确告诉运行时您希望允许这样做。您可以通过将对象标记为 dynamic 来完成此操作。 .

 dynamic myDllClass = assmb.CreateInstance("myNamespace.myClass");

动态将解决您的直接问题,但它是有代价的:

  • 调用动态方法比调用非动态方法慢得多。
  • 此外,您的代码可以正常编译,但在运行时可能会失败。
  • 并且 Intellisense 将无法帮助您建议正确的方法名称(以及大小写,因为 C# 区分大小写)。

但是更好的解决方案是,如果您知道该类的类型(在本例中您将其转换为该类型(或由该类或您的类扩展自的基类实现的接口(interface)) ):

 myClass myDllClass = (myClass) assmb.CreateInstance("myNamespace.myClass");

这需要您向包含 myClass 类的项目添加程序集引用。

您可以通过创建包含基类或接口(interface)的共享程序集来改进模型:

在共享程序集中:

 public interface myInterface
 {
     string publicConString { get; };
     DataTable MethodReturnsDatatable(string sql, string connectionString);
 }

file.dll 中,添加对包含 myInterface 的程序集/项目的引用:

 public class myClass : myInterface{}

在使用 myClass 的项目中,还添加对包含 myInterface 的程序集/项目的引用:

 myInterface myDllClass = (myInterface) assmb.CreateInstance("myNamespace.myClass");

这样您就不需要直接引用 file.dll,允许您在运行时加载不同的实现,但它确实确保您只调用正确的方法,并且你的代码知道如何处理它。

关于c# - 使用反射的对象实例化适用于 VB.NET,但不适用于 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30128583/

相关文章:

c# - 在各种技术之间传递数据

C# 匿名方法不会运行。未设置对象引用

c# - 使用 .Net Core 2 和 Moq,如何设置 HTTP 上下文来伪造身份验证?

c# - WCF 错误架构

c# - 如何从 .NET 使用 VB6 DLL?

sql - 计算 SQL 表中超过 1 行出现 2 个不同值的次数

c# - 从多个表(C#实体)获取数据,通过外键链接,转换为匿名对象

c# - 如何仅在您的应用中禁用 Web 浏览器 'Click Sound'

vb.net - Cognex Insight SetComment 不持久

c# - 匹配进程参数的正则表达式