簡體   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