简体   繁体   中英

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

I'm trying to instantiate an object from a dll without referencing it. I can do it using Reflection in VB.NET but can't figure out how to do it in C#.

In 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

In 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;
    }                
}

I get these two errors:

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 will allow you to do "Late Binding" (when option strict is not used or when it's explicitly allowed through the project properties.) which will let the runtime check whether the object has a certain method before callign it. This is also possible in C#, but then you need to explicitly tell the runtime you want to allow this. You do it by marking the object as dynamic .

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

Dynamic will solve your direct issue, but it comes at a cost:

  • Invoking dynamic methods is is much slower than invoking a non-dynamic method.
  • Plus, your code will compile just fine, but could fail at runtime.
  • And Intellisense will not be able to help you suggest the correct method names (and casing, since C# is case sensitive).

But a better solution would be, if you know the type of the class (which you do in this case, to cast it to that type (or to an Interface implemented by the class or a base class which your class extends from):

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

This would require you to add an assembly reference to the project containing the myClass class.

You can improve your model by creating a shared assembly that contains the base class or interface:

In the shared assembly:

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

In your file.dll , add a reference to the assembly/project containing myInterface :

 public class myClass : myInterface{}

In your project consuming myClass also add a reference to the assembly/project containing myInterface :

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

This way you don't need to have a direct reference to file.dll , allowing you to load different implementations at runtime, but it does ensure that you're only calling proper methods and that your code knows how to deal with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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