例如
BaseClass MyBase()
{
public int Add(BaseClass next)
{
if (this is InheritedA && next is InheritedA)
return 1;
else if (this is InheritedA && next is InheritedB)
return 2;
else if (this is InheritedB && next is InheritedA)
return 3;
else if (this is InheritedB && next is InheritedB)
return 4;
}
}
其中InheritedA
和InheritedB
是它的继承类。事实上,还有更多的 Inherited 类,Add
根据其操作数的顺序和类型返回不同的结果。
我正在考虑使用多态和重载重写它,但是,它变得相当复杂,我必须引入一个辅助方法来解析任一端的类型。
例如
InheritedA myA()
{
public override int Add(BaseClass next)
{
return next.AddTo(this);
}
}
现在我必须将 AddTo
放入 BaseClass
中,并在继承类中覆盖它。
InheritedA myA()
{
public override int AddTo(InheritedA next) { return 1; }
public override int AddTo(InheritedB next) { return 3; }
}
BaseClass myBase()
{
public abstract int Add(BaseClass next);
public abstract int AddTo(InheritedA next);
public abstract int AddTo(InheritedB next);
}
有更好的方法吗?
最佳答案
您正在实现的模式称为双重虚拟分派(dispatch)。
单个虚拟分派(dispatch)根据接收方的运行时类型和编译时类型选择调用哪个方法的论点。这是传统的虚拟调度:
abstract class Animal {}
class Tiger : Animal {}
class Giraffe : Animal {}
class B
{
public virtual void M(Tiger x) {}
public virtual void M(Animal x) {}
}
class D : B
{
public override void M(Tiger x) {}
public override void M(Animal x) {}
}
...
B b = whatever;
Animal a = new Tiger();
b.M(a);
调用了哪个方法? B.M(Tiger)
和 D.M(Tiger)
未被选中;我们根据参数的编译时类型拒绝它们,即 Animal。但是我们在运行时根据 whatever
是否是 new B() 选择调用
或 B.M(Animal)
还是 D.M(Animal)
new D()
。
Double virtual dispatch 根据两个东西的运行时类型选择调用哪个方法。如果 C# 支持双重虚拟分派(dispatch),而它不支持,那么运行时分派(dispatch)将转到 B.M(Tiger)
或 D.M(Tiger)
,即使编译时类型为参数是Animal。
不过,C# 4 确实支持动态 分派(dispatch)。如果你说
dynamic b = whatever;
dynamic a = new Tiger();
b.M(a);
然后 M 的分析将完全在运行时使用 b
和 a
的运行时类型完成。这要慢得多,但它确实有效。
或者,如果您想执行双重虚拟分派(dispatch)并在编译时获得尽可能多的分析,那么标准方法是实现访问者模式,您可以轻松地在 Internet 上查找。
关于c# - 如何使用多态+重载改进这种方法以减少IS(类型检查)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9892660/