[英]Object instantiation using Reflection works in VB.NET but not C#
I'm trying to instantiate an object from a dll without referencing it. 我正在尝试实例化dll中的对象而不引用它。 I can do it using Reflection in VB.NET but can't figure out how to do it in C#. 我可以在VB.NET中使用Reflection来做到这一点,但无法弄清楚如何在C#中做到这一点。
In VB.NET: 在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#: 在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 错误1'对象'不包含'publicConString'的定义,找不到扩展方法'publicConString'接受类型为'object'的第一个参数(您是否缺少using指令或程序集引用?)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 错误2'对象'不包含'MethodReturnsDatatable'的定义,找不到扩展方法'MethodReturnsDatatable'接受类型为'object'的第一个参数(您是否缺少using指令或程序集引用?)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. VB.NET将允许您执行“后期绑定”(当未使用option strict
时,或者在项目属性中明确允许使用它时)。这将使运行时在调用该对象之前检查该对象是否具有某种方法。 This is also possible in C#, but then you need to explicitly tell the runtime you want to allow this. 这在C#中也是可能的,但是随后您需要明确告诉运行时您要允许这样做。 You do it by marking the object as dynamic . 您可以通过将对象标记为dynamic来实现 。
dynamic myDllClass = assmb.CreateInstance("myNamespace.myClass");
Dynamic will solve your direct issue, but it comes at a cost: Dynamic将解决您的直接问题,但这需要付出一定的代价:
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. 这将需要您向包含myClass
类的项目添加程序集引用。
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
: 在您的file.dll
,添加对包含myInterface
的程序集/项目的myInterface
:
public class myClass : myInterface{}
In your project consuming myClass
also add a reference to the assembly/project containing myInterface
: 在消耗myClass
的项目中,还添加对包含myInterface
的程序集/项目的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. 这样,您无需直接引用file.dll
,从而允许您在运行时加载不同的实现,但可以确保仅调用正确的方法,并且代码知道如何处理它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.