我在项目中添加了一个DLL的引用,并且成功地能够访问该DLL的方法/类。
DLL中的代码:(我无权修改此代码)
//Dll: myDllName
Namespace myNamespace
Public Class MyClass
Private Sub New(ByVal parameter1 As Int64)
//Set some values
End Sub
Public Shared Function MyPublicFunction(ByVal Parameter1 As Int64,ByVal Parameter2 As INt64,ByVal Parameter2 As Int64) As MyClass
Dim retMyClass As New MyClass(Parameter1)
//Set Other Values
Return retMyClass
End Function
Public Function Post() As Boolean
//Do some operation
End Function
End Class
End Namespace
我在上面调用DLL的代码:
Dim myObj As myDllName.myNamespace.MyClass
myObj = myDllName.myNamespace.MyClass.MyPublicFunction(Parameter1, Parameter2, Parameter3)
myObj.Prop1 = MyVal1
myObj.Prop2 = MyVal2
myObj.Prop3 = MyVal1
myObj.Post()
现在我的要求是我想在不向项目添加DLL引用的情况下实现上述任务。 所以我试图通过反思实现这一点。
Dim assembly As Reflection.Assembly = Reflection.Assembly.LoadFile("..\\myDllName.dll")
Dim t As Type = assembly.GetType("myDllName.myNamespace.MyClass")
Dim woFacadeinst As Object = Activator.CreateInstance(t)
但是在对象初始化时,它会抛出类型为
的构造函数的错误myDllName.myNamespace.MyClass
未找到。
我认为这是因为我的DLL引用类中的Private NEW方法。 有人可以帮忙吗?
答案 0 :(得分:1)
对于参数化构造函数,请使用GetConstructors()
和Invoke()
而不是Activator.CreateInstance()
,如下所示:
Dim constructor = t.GetConstructors(BindingFlags.NonPublic Or BindingFlags.Instance)
Dim woFacadeinst As Object = constructor(0).Invoke(New Object() {5})
因为需要更多时间,请查看此link中的图表,如果性能对您来说真的很重要,请尝试编译lambda表达式,它比两者都快。
答案 1 :(得分:0)
您遇到此异常,因为使用此行
Dim woFacadeinst As Object = Activator.CreateInstance(t)
你试图调用一个不存在的参数less constructor。
因此,您必须使用更多参数调用Activator.CreateInstance()
以将所需参数传递给构造函数。
Private Sub New(ByVal parameter1 As Int64)
'Set some values
End Sub
通常在C#中我使用了以下代码段:
var woFacadeinst = Activator.CreateInstance( typeof(Class1), BindingFlags.NonPublic | BindingFlags.Instance,
null, new object[] { 5 }, null );
和vb.Net:
Dim woFacadeinst As Object = Activator.CreateInstance( GetType(Class1),
BindingFlags.NonPublic Or BindingFlags.Instance,
Nothing, New Object(){ 5 }, Nothing)
获取私有构造函数的技巧是正确的Bindingflags
并使用new object[]{ 5 }
设置构造函数所需的参数。
提示: 有关性能问题,请查看Ali Ezzat Odeh' Answer。
如果您想使用GetConstructor()
方法,可以执行以下C#代码段:
var test = typeof(Class1).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance,
null, new Type[] { typeof(Int64) }, null )
?.Invoke( new object[] { 64 } );
作为C#示例:
班级:
public class Class1
{
private Class1(string myString)
{
MyIntProperty = 42;
MyStringProperty = myString;
}
private Class1(int myInt)
{
MyIntProperty = myInt;
MyStringProperty = "default";
}
private Class1(Int64 myInt64)
{
MyInt64Property = myInt64;
MyStringProperty = "default";
}
public string MyStringProperty { get; set; }
public int MyIntProperty { get; set; }
public Int64 MyInt64Property { get; set; }
}
和测试代码段:
string testString = "Test";
int testInt = 123;
var objArray = new object[1];
objArray[0] = testString;
var testClass1 = Activator.CreateInstance( typeof(Class1), BindingFlags.NonPublic | BindingFlags.Instance,
null, objArray, null );
objArray[0] = testInt;
var testClass2 = Activator.CreateInstance( typeof(Class1), BindingFlags.NonPublic | BindingFlags.Instance,
null, objArray, null );
var testCtorClass = typeof(Class1).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance,
null, new Type[] { typeof(Int64) }, null )
?.Invoke( new object[] { 64 } );
答案 2 :(得分:0)
你可以尝试var myClass = FormatterServices.GetUninitializedObject(typeof(MyClass));
这个api不使用任何构造函数,因此它没有任何构造函数要求。