根据类型切换行为的最佳方法

Jon*_*art 6 c# polymorphism

可能重复:
C# - "开启类型"有比这更好的选择吗?

考虑经典:

class Widget { }
class RedWidget : Widget { }
class BlueWidget : Widget { }
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,在我的用户界面中,我可以对待所有Widget相同的内容.但是,我需要ifswitch通过一些细微差别.

可能的方法:

枚举指标 - 由构造函数设置

enum WidgetVariety { Red, Blue }

class Widget {
    public WidgetVariety Variety { get; protected set; }
}

class RedWidget : Widget {
    public RedWidget() {
        Variety = Red;
    }
}

// Likewise for BlueWidget...

switch (mywidget.Variety) {
case WidgetVariety.Red:
    // Red specific GUI stuff

case WidgetVariety.Blue:
    // Blue specific GUI stuff
}
Run Code Online (Sandbox Code Playgroud)

使用 is

Widget w = ...;
if (w is RedWidget) {
    (RedWidget)w ...
}
else if (w is BlueWidget) {
    (BlueWidget)w ...
}
Run Code Online (Sandbox Code Playgroud)

我采用这个的原因是1)大多数代码已经用这种方式编写,但更加丑陋.2)90%的代码是相同的 - 基本上只需要根据类型对GridView中的一列进行不同的处理.

你会推荐哪个?(或者任何人都有更好的解决方案?)


编辑我知道我可能会被推荐给访客模式,但在这种情况下,这似乎很复杂,因为稀疏的细微差别.

编辑2 因此,我很难解决的一个特殊区别是这两个类型的列不同.在一种情况下,它检索一个bool值,并将其分配给网格单元格.在另一种情况下,它获取一个字符串值.

我想在这种情况下,我可以明确地定义:

public object virtual GetColumn4Data();

public override GetColumn4Data() { return m_boolval; }

public override GetColumn4Data() { return m_mystring; }
Run Code Online (Sandbox Code Playgroud)

由于使用,我最初感觉不对object.但是,这我在单元格中分配的属性的类型,所以当然这是有道理的!

今天办公室太长了似乎......

pho*_*oog 9

还有另一种可能性.使用虚拟调度:

class Widget
{
    public virtual void GuiStuff() { }
} 
class RedWidget : Widget
{
    public override void GuiStuff()
    {
        //... red-specific GUI stuff
        base.GuiStuff();
    }
} 
class BlueWidget : Widget
{
    public override void GuiStuff()
    {
        //... blue-specific GUI stuff
        base.GuiStuff();
    }
} 
Run Code Online (Sandbox Code Playgroud)


jor*_*hmv 5

子类型多态性是最好的解决方案,避免这种检查是OO创建的主要原因之一.

Widget可能有一个方法DoSomething()(很可能是抽象),然后RedWidgetBlueWidget将其覆盖.

另请参阅Martin Fowler的替换条件多态性:

看到:您有一个条件,根据对象的类型选择不同的行为.

重构:将条件的每一条腿移动到子类中的重写方法.使原始方法抽象化.

  • 我不同意[这种]多态性是"为什么OO被创造"的想法; 它更像是一些"OO语言"的*效果*.但是,其他位为+1.(有多种多态性而不是无聊 - 而且很危险! - 例如,在C#/ Java中发现的单一调度子类型.) (2认同)