【发布时间】:2020-01-22 17:11:29
【问题描述】:
我想在运行时构建一个动态类型,将多个现有类型组合在一个动态类型中,以模拟以下 python 场景:
class A(object):
def Confirm(self):
print("A")
class B(A):
def Confirm(self):
super().Confirm()
print("B")
class C(A):
def Confirm(self):
print("C")
super().Confirm()
class D(A):
def Confirm(self):
print("D")
super().Confirm()
print("DD")
class E(B,C,D):
pass
我得到了以下输出:
C
D
A
DD
B
所以调用堆栈尊重 super() 调用之前和之后的代码顺序,在 super() 调用之前执行所有代码,然后 super 调用自身,最后是 super() 调用之后的最后一部分代码。 我想在 c# 中模拟这种行为。
public class A
{
public virtual void Confirm()
{
Console.Writeline("A");
}
}
public class B : A
{
public virtual void Confirm()
{
base.Confirm();
Console.Writeline("B");
}
}
public class C : A
{
public virtual void Confirm()
{
Console.Writeline("C");
base.Confirm();
}
}
public class D : A
{
public virtual void Confirm()
{
Console.Writeline("D");
base.Confirm();
Console.Writeline("DD");
}
}
public class E : A
{
public virtual void Confirm()
{
// BEFORE base
Console.Writeline("C"); // C.Confirm() without base, only code before base.Confirm()
Console.Writeline("D"); // D.Confirm() without base only code before base.Confirm()
// BASE
base.Confirm(); // base itself (A)
// AFTER base
Console.Writeline("DD"); // return to D.Confirm() only the code after base.Confirm()
Console.Writeline("B"); // B.Confirm() have only a code after base.Confirm() call
}
}
我想我可以通过使用System.Reflection.Emit 来解决这个问题,但我不知道这是否可行。
【问题讨论】:
-
在撰写本文时,C# 不支持多继承。
-
使用
call而不是callvirt。不过,这是一个 hack。 -
你从来没有向我们展示过产生该输出的调用。当我读到它时,Python 使用了 Diamond Problem Resolution 的“第一个匹配”变体。 D, A, DD 我明白了——它只是 D.Confirm()。但是 C 和 B 怎么会出现在那个名单上呢?在那些确切位置上要少得多?
标签: c# multiple-inheritance cil