派生类的返回值

问题描述:

鉴于这些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不必是抽象的工作,但它必须是虚拟的。

+0

+1我会试试这个,谢谢。 – egrunin 2010-08-07 20:04:24

+0

@egrunin:如果你完全不能改变这些类,那么你显然不能这样做,你必须诉诸使用“如果这是类型的......否则,如果这是其他类型......” 。但是,您可以在客户端编写自己的包装类来为您解决这个问题。包装类将这些类作为他们的胆量,并提供一个可以进行多态性的公共接口。你仍然需要“如果这种类型,然后......”,但你只需要写一次,它将类型转换为你的包装。 – 2010-08-07 20:07:36

你可以尝试结合handleXHandleSysState和压倒一切的它在这两个NormalFoobar来执行特定任务。这可能不是完美的解决方案,但它看起来相对整齐。如果您需要从其他来源输入数据,请将它们作为参数传递给它们?

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做的,但它可以很好地工作。

+0

我无法更改这些类,它们是自动生成的。当WDSL改变时,任何定制都将丢失。否则,是的,那很好。 – egrunin 2010-08-07 19:54:27

+0

啊。那么,那根本不行。你可以将它们转换为具有处理函数以处理任何差异的通用类型吗? – ssube 2010-08-07 19:56:50

+5

只需标记您的自定义班级部分。 svcutil已经在生成的类中这样做了。您可以将所有自定义代码放入自己的类中,而无需担心在wsdl更改时生成的代码。 – 2010-08-07 20:00:25