这是一个具有挑战性的问题,让我在今天编写代码时感到难过。假设我正在运行Sub Test1()
和Test2()
,并希望打印出我传入的对象的实例的Shadows
方法的值使用以下限制TestCall()
(见下文 - 更清楚):
Class A
,B
和C
Sub Test1()
和Sub Test2()
if
,select case
等语句,试图找出传入的参数的类型,然后执行CType(o, <C or B>).Method()
。假设有无数个类,例如B
和C
,所有类都继承自A
或B
或C
和阴影Method
< / LI>
Shadows
更改为Overridable/Overrides
)我想动态执行等效的CType(o, C).Method()
并打印出C.Method
用于Test1,然后动态执行等效的CType(o, B).Method()
并打印出B.Method
。
<TestFixture()> _
Public Class Test
<Test()>
Public Sub Test1()
Dim o As A = New C
TestCall(o) '<-- THIS SHOULD PRINT "C.Method"
End Sub
Public Sub Test2()
Dim o As A = New B
TestCall(o) '<-- THIS SHOULD PRINT "B.Method"
End Sub
Public Sub TestCall(ByVal o as A)
o.Method()
End Sub
Class A
Public Sub Method()
Console.WriteLine("A.Method")
End Sub
End Class
Class B
Inherits A
Public Shadows Sub Method()
Console.WriteLine("B.Method")
End Sub
End Class
Class C
Inherits B
Public Shadows Sub Method()
Console.WriteLine("C.Method")
End Sub
End Class
End Class
答案 0 :(得分:2)
你的问题来自这样一个事实:如果你使用关键字Shadows
,你创建一个与隐藏原始方法相同名称的新方法,即覆盖可覆盖(虚拟)方法的反转。
我能想到动态解决这个问题的唯一方法是找出声明类型,查询某个签名的现有方法的类型,然后调用该方法。
如果这就是您所追求的,那么TestCall的以下代码(对不起,在C#中,但您使用C#标记了您的问题)将会这样做。您唯一需要知道的是方法的名称,您在原始情况下也必须知道。
public void TestCall(A someAorBorC)
{
// store declaring type
Type T = someAorBorC.GetType();
// find shadowed method
var method = (from m in T.GetMethods()
where m.DeclaringType == T
&& m.Name == "Method"
select m).SingleOrDefault();
if (method == null)
throw new Exception("Method 'Method' not found in declaring type");
// call method
method.Invoke(someAorBorC, null);
}
// Console:
C.Method
B.Method
答案 1 :(得分:0)
另一种方法,就像我几天前发现的那样没有反思:
Public Sub TestCall(ByVal someAorBorC as A)
Convert.ChangeType(someAorBorC, someAorBorC.GetType()).Method()
End Sub