问题描述
我正在尝试调用类"CMyClass"的方法"MyMethod".此方法的参数类型为"CBaseClass",而我正在传递类型为"CDerivedClass"的对象.
I'm trying to call the method 'MyMethod' of class 'CMyClass'. This method has a parameter of type "CBaseClass", and I'm passing an object of type "CDerivedClass".
Class CBaseClass
Public m_AMember As String
Sub MethodOne()
// DoSomething
End Sub
End Class
Class CDerivedClass
Inherits CBaseClass
Public m_MyMember As Integer
Sub MethodTwo()
// DoSomething
End Sub
End Class
Class CMyClass
Sub MyMethod(ByVal obj As CBaseClass)
// DoSomething
End Sub
End Class
Sub Main()
'load assembly
Dim objAssembly As Assembly = Assembly.LoadFrom("myfile.dll")
'create class instance and MethodInfo object
Dim t As Type = objAssembly.GetType("MyNamespace.CMyClass")
Dim obj As Object = Activator.CreateInstance(t)
Debug.Assert(obj IsNot Nothing)
Dim m As MethodInfo = t.GetMethod("MyMethod")
Debug.Assert(m IsNot Nothing)
'Init arguments (only one)
Dim par As New CDerivedClass()
Dim parameters As Object() = New Object(0) {par}
'invoke method
m.Invoke(obj, parameters) '<<<< ArgumentException here!
End Sub
参数异常表明类型'MyNamespace.CDerivedClass'的对象不能转换为类型'MyNamespace.CBaseClass'.
The argument exception says "object of type 'MyNamespace.CDerivedClass' cannot be converted to type 'MyNamespace.CBaseClass'.
我在MyMethod签名中将"ByRef"更改为"ByVal",但未进行任何更改.我试图通过以下方式更改"par"对象的类型:
I changed "ByRef" to "ByVal" in MyMethod signature, but nothing changed.I tried to change type of 'par' object with:
Dim par As CBaseClass = New CDerivedClass()
没有成功.如何使用派生类的实例正确调用方法"MyMethod"?非常感谢.
without success.How I can invoke correctly the method "MyMethod" with an instance of derived class?Thank you very much.
推荐答案
最后,我使用序列化解决了...
Finally I solved using serialization...
所以'par'是包含调用项目中CDerivedClass类型的序列化对象的字符串.
So 'par' is the string containing the serialized object of type CDerivedClass in the calling project.
MyMethod更改为:
MyMethod is changed to:
MyMethod(xml_CBaseClass As String)
在dll项目中,将字符串参数xml_CBaseClass反序列化以创建CBaseClass的对象.
In dll project the string parameter xml_CBaseClass is deserialized creating an object of CBaseClass.
注意:由于我有派生类型,派生类的反序列化带来了另一个问题.解决方案是 https://stackoverflow.com/a/590711/1315873 (我做了一些改动,使用StringWriter进行序列化,使用StringReader进行反序列化,而不是使用MemoryBuffer.)
Note: since I have derived type, Deserialization of derived class give another problem. The solution is https://stackoverflow.com/a/590711/1315873(I just made a little change, using StringWriter for serialization, StringReader for deserialization, instead of using MemoryBuffer).
CBaseClass具有固定的派生类型,因此我将它们写为硬编码,但是要灵活一些,您可以执行以下操作:
CBaseClass has fixed derived types so I wrote them hard-coded, but to be flexible you can do something like:
Dim subTypes as New List(Of Type) '<- all classes derived from 'myType'
For Each t In myType.Assembly.GetTypes()
If t.IsSubclassOf(myType) Then
subTypes.Add(t)
End If
Next
CBaseClass及其所有派生类必须具有不带参数的构造函数New().
CBaseClass and all its derivated classes must have constructor New() without parameters.
由于我不知道程序集的名称,所以我使用LoadFrom()来加载程序集(我使用Dir()从已知的固定文件夹中获取所有程序集).
I load assemblies using LoadFrom() since I don't know their names (I use Dir() to get all them from a known fixed folder).
这篇关于通过反射调用成员,并将派生类作为参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!