如何通过遮蔽父类实现的父's类型调用成员
本文关键字:类型 成员 调用 何通过 父类 实现 | 更新日期: 2023-09-27 18:04:31
这是一个具有挑战性的问题,当我今天编码时,我被它难住了。假设我正在运行Sub Test1()
和Test2()
,并希望使用以下限制打印出我传递给TestCall()
的对象的实例的Shadows
方法的值(见下面-更清楚):
- 不能更改
Class A
、B
和C
的内容 - 不能更改
Sub Test1()
和Sub Test2()
- TestCall()不能有
if
,select case
等语句,试图找出传入的参数的类型,然后做CType(o, <C or B>).Method()
。假设有无限数量的类,如B
和C
,它们都继承自A
或B
或C
,并影子Method
- 你不能改变sub的属性(即你不能将
Shadows
更改为Overridable/Overrides
)
我想动态执行CType(o, C).Method()
的等效物并为Test1打印出C.Method
,然后动态执行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
您的问题来自于这样一个事实:如果您使用关键字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
几天前我发现了另一种方法:
Public Sub TestCall(ByVal someAorBorC as A)
Convert.ChangeType(someAorBorC, someAorBorC.GetType()).Method()
End Sub