我正在尝试从 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/