好的,我正在尝试执行以下操作:
protected bool ValidAdvert(Base item)
{
throw ThisIsAnAbstractClassException();
}
protected bool ValidAdvert(Derived1 item)
{
return ADerived1SpecificPredicate;
}
protected bool ValidAdvert(Derived2 item)
{
return ADerived2SpecificPredicate;
}
当Base类传递给方法时,调用方法的Derived类版本。基类是抽象的,所以理论上这应该是可能的吗?
在某人说出有关在类本身上重载方法的事情之前,方法内部的逻辑依赖于大量不同的条件,其中没有一个是相关的,并且没有一个直接与Base / Derived类相关(例如作为登录状态等。)
答案 0 :(得分:6)
如果发现双重调度过于干扰,可以通过反射调用方法并动态解决正确的重载。
protected bool ValidAdvert(Base item)
{
if (item.GetType() == typeof(Base))
throw new ThisIsAnAbstractClassException();
Type type = typeof(CurrentClass);
MethodInfo method = type.GetMethod("ValidAdvert",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new Type[] { item.GetType() },
null);
return (bool)method.Invoke(this, new object[] { item });
}
protected bool ValidAdvert(Derived1 item)
{
return ADerived1SpecificPredicate;
}
protected bool ValidAdvert(Derived2 item)
{
return ADerived2SpecificPredicate;
}
这种模式称为MultipleDispatch,而通过反射调用方法比直接调用方法要慢(如果方法每秒调用少于几百次,则不会产生开销),它具有不需要像Double Dispatch模式那样修改类层次结构的好处。
当c#4.0出现动态关键字时,这将更加容易:
protected bool ValidAdvert(Base item)
{
if (item.GetType() == typeof(Base))
throw new ThisIsAnAbstractClassException();
dynamic dynamicThis = this;
return (bool)dynamicThis.ValidAdvert(item as dynamic);
}
答案 1 :(得分:5)
使用double dispatch的理想场所:
class Base
{
public abstract bool IsValid(IAdvertValidator validator);
}
class Derived1 : Base
{
public bool IsValid(IAdvertValidator validator)
{
return validator.ValidAdvert(this);
}
}
class Derived2 : Base
{
public bool IsValid(IAdvertValidator validator)
{
return validator.ValidAdvert(this);
}
}
interface IAdvertValidator
{
bool ValidAdvert(Derived1 d1);
bool ValidAdvert(Derived2 d2);
}
答案 2 :(得分:0)
我不确定你将如何拥有一个实际上不是派生类实例的基类实例。由于基类是抽象的,因此无法实例化。我想它会匹配任何没有特定签名的派生类,但这似乎不是你想要的。