派生类的返回值
问题描述:
鉴于这些C#类(WCF所产生的,我不能改变这些):派生类的返回值
public SysState GetSysState();
public class SysState { /* nothing much here */}
public class Normal : SysState { /* properties & methods */ }
public class Foobar : SysState { /* different properties & methods */ }
我的代码(目前):
SysState result = GetSysState();
if (result is Normal) HandleNormal((Normal) result);
if (result is Foobar) HandleFoobar((Foobar) result);
我的问题:我一直觉得我错过了一些明显的东西,我不应该明确地检查类型。我有一个高级时刻?
答
使用虚拟方法。把你的代码放在它们所操作的类中,而不是在一些获得对类的引用的代码中。
public class SysState {
/* nothing much here, except...: */
public abstract virtual void DoSomething();
}
public class Normal : SysState {
/* properties & methods */
public override void DoSomething()
{
// ...
}
}
public class Foobar : SysState {
/* different properties & methods */
public override void DoSomething()
{
// ...
}
}
SysState result = SomeFunctionThatReturnsObjectDerivedFromSysState();
result.DoSomething();
这将执行派生类的DoSomething方法。这被称为多态性,并且是最自然的(有些人会认为只有正确)使用继承。
请注意,SysState.DoSomething不必是抽象的工作,但它必须是虚拟的。
答
你可以尝试结合handleX
置Handle
在SysState
和压倒一切的它在这两个Normal
和Foobar
来执行特定任务。这可能不是完美的解决方案,但它看起来相对整齐。如果您需要从其他来源输入数据,请将它们作为参数传递给它们?
public class SysState
{
public bool Process(Information info)
{
return (info.Good);
}
}
public class Normal
{
public bool Process(Information info)
{
return doStuff();
}
}
public class Foobar
{
public bool Process(Information info)
{
return diePainfully();
}
}
显然只是一个例子,不知道什么HandleNormal和HandleFoobar做的,但它可以很好地工作。
+1我会试试这个,谢谢。 – egrunin 2010-08-07 20:04:24
@egrunin:如果你完全不能改变这些类,那么你显然不能这样做,你必须诉诸使用“如果这是类型的......否则,如果这是其他类型......” 。但是,您可以在客户端编写自己的包装类来为您解决这个问题。包装类将这些类作为他们的胆量,并提供一个可以进行多态性的公共接口。你仍然需要“如果这种类型,然后......”,但你只需要写一次,它将类型转换为你的包装。 – 2010-08-07 20:07:36