具有继承参数的重载函数
Overloaded functions with inherited parameter
我正在尝试做这样的事情,但我收到错误,大致如下:
Cannot convert from AbstractExampleClass to SpecificExampleClassA.
所以我可能在使用这段代码时走错了方向,谁能告诉我哪里出了问题以及如何解决它。
public abstract class AbstractExampleClass
{
// Code goes here
}
public class SpecificExampleClassA : AbstractExampleClass
{
}
public class SpecificExampleClass : AbstractExampleClass
{
}
public class handler
{
public void Handle(AbstractExampleClass aec)
{
HandleSpecific(aec);
}
public void HandleSpecific(SpecificExampleClassA a)
{
// DoSomething
}
public void HandleSpecific(SpecificExampleClassB b)
{
// DoSomething Else
}
}
重载在编译时解决,因此您不能指望它根据 aec
的 运行时类型 来决定调用哪个重载。 要调用的重载必须在编译时决定。
你真正需要的是“subtyping" kind of polymorphism (aka just "polymorphism" in C# terminology), not ad hoc polymorphism(又名"overloading")。
改为在子类中移动处理程序方法:
public abstract class AbstractExampleClass
{
public abstract void Specific();
}
public class SpecificExampleClassA : AbstractExampleClass
{
public override void Specific()
{
// DoSomething
}
}
public class SpecificExampleClass : AbstractExampleClass
{
public override void Specific()
{
// DoSomething Else
}
}
public class handler
{
public void Handle(AbstractExampleClass aec)
{
aec.Specific();
}
}
可以由 Visitor Pattern
处理
public abstract class AbstractExampleClass
{
public abstract void Accept( Handler handler );
}
public class SpecificExampleClassA : AbstractExampleClass
{
public override Accept( Handler handler )
{
handler.HandleSpecific( this );
}
}
public class SpecificExampleClass : AbstractExampleClass
{
public override Accept( Handler handler )
{
handler.HandleSpecific( this );
}
}
public class Handler // the Visitor
{
public void Handle(AbstractExampleClass aec)
{
aec.Accept( this );
}
public void HandleSpecific(SpecificExampleClassA a) // visit method
{
// DoSomething
}
public void HandleSpecific(SpecificExampleClassB b) // visit method
{
// DoSomething Else
}
}
如果你真的必须这样做,你可以这样做:
public void Handle(AbstractExampleClass aec)
{
switch (aec)
{
case SpecificExampleClassA a:
HandleSpecific(a);
break;
case SpecificExampleClassB b:
HandleSpecific(b);
break;
default:
throw new Exception($"What do I do with a '{aec?.GetType()}'?");
}
}
但如果您被允许这样做,我推荐一种类似于 Sweeper 回答中的方法。
我正在尝试做这样的事情,但我收到错误,大致如下:
Cannot convert from AbstractExampleClass to SpecificExampleClassA.
所以我可能在使用这段代码时走错了方向,谁能告诉我哪里出了问题以及如何解决它。
public abstract class AbstractExampleClass
{
// Code goes here
}
public class SpecificExampleClassA : AbstractExampleClass
{
}
public class SpecificExampleClass : AbstractExampleClass
{
}
public class handler
{
public void Handle(AbstractExampleClass aec)
{
HandleSpecific(aec);
}
public void HandleSpecific(SpecificExampleClassA a)
{
// DoSomething
}
public void HandleSpecific(SpecificExampleClassB b)
{
// DoSomething Else
}
}
重载在编译时解决,因此您不能指望它根据 aec
的 运行时类型 来决定调用哪个重载。 要调用的重载必须在编译时决定。
你真正需要的是“subtyping" kind of polymorphism (aka just "polymorphism" in C# terminology), not ad hoc polymorphism(又名"overloading")。
改为在子类中移动处理程序方法:
public abstract class AbstractExampleClass
{
public abstract void Specific();
}
public class SpecificExampleClassA : AbstractExampleClass
{
public override void Specific()
{
// DoSomething
}
}
public class SpecificExampleClass : AbstractExampleClass
{
public override void Specific()
{
// DoSomething Else
}
}
public class handler
{
public void Handle(AbstractExampleClass aec)
{
aec.Specific();
}
}
可以由 Visitor Pattern
处理public abstract class AbstractExampleClass
{
public abstract void Accept( Handler handler );
}
public class SpecificExampleClassA : AbstractExampleClass
{
public override Accept( Handler handler )
{
handler.HandleSpecific( this );
}
}
public class SpecificExampleClass : AbstractExampleClass
{
public override Accept( Handler handler )
{
handler.HandleSpecific( this );
}
}
public class Handler // the Visitor
{
public void Handle(AbstractExampleClass aec)
{
aec.Accept( this );
}
public void HandleSpecific(SpecificExampleClassA a) // visit method
{
// DoSomething
}
public void HandleSpecific(SpecificExampleClassB b) // visit method
{
// DoSomething Else
}
}
如果你真的必须这样做,你可以这样做:
public void Handle(AbstractExampleClass aec)
{
switch (aec)
{
case SpecificExampleClassA a:
HandleSpecific(a);
break;
case SpecificExampleClassB b:
HandleSpecific(b);
break;
default:
throw new Exception($"What do I do with a '{aec?.GetType()}'?");
}
}
但如果您被允许这样做,我推荐一种类似于 Sweeper 回答中的方法。