繁体   English   中英

使用反射的对象实例化在VB.NET中有效,但在C#中不起作用

[英]Object instantiation using Reflection works in VB.NET but not C#

我正在尝试实例化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;
    }                
}

我收到以下两个错误:

错误1'对象'不包含'publicConString'的定义,找不到扩展方法'publicConString'接受类型为'object'的第一个参数(您是否缺少using指令或程序集引用?)C:\\ Users \\ Username \\ Desktop \\ C#\\ FormTest \\ FormTest \\ Form1.cs 29 34 FormTest

错误2'对象'不包含'MethodReturnsDatatable'的定义,找不到扩展方法'MethodReturnsDatatable'接受类型为'object'的第一个参数(您是否缺少using指令或程序集引用?)C:\\ Users \\ Username \\ Desktop \\ C#\\ FormTest \\ FormTest \\ Form1.cs 30 33 FormTest

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

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

Dynamic将解决您的直接问题,但这需要付出一定的代价:

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

但是,如果您知道类的类型(在这种情况下,您可以将其强制转换为该类型)(或者转换为由该类实现的接口或您的类从其继承的基类实现),则更好的解决方案是:

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

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

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

在共享程序集中:

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

在您的file.dll ,添加对包含myInterface的程序集/项目的myInterface

 public class myClass : myInterface{}

在消耗myClass的项目中,还添加对包含myInterface的程序集/项目的myInterface

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM