【问题标题】:how inheritance replace the switch case?继承如何替换switch case?
【发布时间】:2009-09-11 02:09:38
【问题描述】:

我正在使用 C# Switch 案例,如何使用继承来替换。 案例就像 1,2,3,4 所以 我如何实现它。

例如:

    public Blocks(int code)
    {
         bool[,] shp1;

        switch (code)
        {
            case 1:
                this._Width = 4;
                this._Height = 1;
                this._Top = 0;
                this._Left = 4;

                shp1 = new bool[_Width, _Height];
                shp1[0, 0] = true;
                shp1[1, 0] = true;
                shp1[2, 0] = true;
                shp1[3, 0] = true;
                this.Shape = shp1;
                break;

            case 2:
                this._Width = 2;
                this._Height = 2;
                this._Top = 0;
                this._Left = 4;

                shp1 = new bool[_Width, _Height];
                shp1[0, 0] = true;
                shp1[0, 1] = true;
                shp1[1, 0] = true;
                shp1[1, 1] = true;
                this.Shape = shp1;
                break;


            default:
                throw new ArgumentException("Invalid Block Code");
        }
    }

【问题讨论】:

  • 你的问题不是很清楚。请提供更多信息。
  • 请更准确。举一个你的开关出现的代码示例。
  • 你能解释一下“我如何使用继承替换”的意思吗?

标签: c#


【解决方案1】:

基本思想是,您可以拥有不同类型的对象,这些对象具有相同方法的不同实现,为该类型的对象做正确的事情,而不是拥有一个根据状态决定做什么的方法。

假设您现在有一个 Car 类,并且值 (1, 2, 3, ...) 指的是各种制动配置。在您当前的 Brake() 方法中,您的代码如下所示:

public class Car
{
    public void Brake()
    {
          switch (this.BrakeType)
          {
              case 1:  // antilock brakes
                ....
              case 2:  // 4-wheel disc brakes, no antilock
                ....
              case 3:  // rear-drum, front-disc brakes
                ....

          }
     }
}

您真正想做的是拥有不同的类来实现 Brake 方法。在这种情况下,我会为每种刹车类型设置一个 BrakeStrategy。为汽车对象分配正确的 BrakeStrategy 为其配置,然后简单地从 Brake 方法中调用策略方法。

public class Car
{
     public BrakeStrategy BrakeStrategy { get; set; }

     public void Brake()
     {
         this.BrakeStrategy.Brake();
     }
}

public class ABSBrakes : BrakeStrategy
{
     public void Brake()
     {
        ... do antilock braking...
     }
}

var car = new Car { BrakeStrategy = new ABSBrakes(), ... };
car.Brake();  // does ABS braking

【讨论】:

  • 谢谢这个例子!但是你能告诉我我们在哪里以及如何移动决策(即我们怎么知道我们必须做BrakeStrategy = ABSBrakes(),而不是= ReadDrunBrakes()?)现在切换到这里了吗?我的问题有意义吗?
  • 您确实必须有某种决策结构来创建您想要使用的制动策略。这可以转移到您确实使用 switch 语句的工厂模式,但是,该语句将远没有原始语句复杂。除此之外,在需要时引入新的制动策略要容易得多。
  • @Preets - @Frederik 是正确的——你确实需要一些方法来确定要创建什么类型的东西。这可以通过使用工厂的配置来完成——工厂读取配置,配置指定要创建的策略类型(按名称)。即使您最终使用决策树——也可以将其放入专门用于创建对象的类中,而不是将操作逻辑传播到整个类中。也就是说,switch语句是在对象被创建的地方本地化的,而不是在每个方法中都使用来确定如何操作这个对象。
  • 雾散了!谢谢特万佛森! SO 将它的成功归功于像你这样的人。
【解决方案2】:

您可以应用Strategy 模式。
但是,如果你明白我的意思,你必须确保你不是想用枪杀死一只苍蝇。 确保你没有引入更多的复杂性然后你试图删除。 在某些情况下,将 switch 语句替换为策略是一个很好的解决方案,而在其他情况下则不然。

当我现在看到你的代码时,我想我会选择某种工厂模式......

【讨论】:

  • 弗雷德里克,你明白这个问题了吗?
  • 是的,我愿意。您可以使用多态性根据特定条件执行不同的功能。对于存在的每个条件,您都可以创建一个类(从相同的基类型继承)并将逻辑封装到该类中,而不是将其放在一个 switch 语句中。请参阅我关于策略模式的链接。
  • 这是我理解的,但我不想切换大小写它仍在使用 switch.. 谢谢 ...
【解决方案3】:

如果您使用继承,您仍然可以动态更改实现,但无需使用 switch 语句。

以上面的 BrakeType 为例:

Dictionary<BrakeType, BrakeStrategy> strategyList = new Dictionary<BrakeType, BrakeStrategy>();

strategyList.Add(BrakeType.ABS, new ABSBrakes());
strategyList.Add(BrakeType.Disc, new DiscBrakes());
strategyList.Add(BrakeType.RearDrum, new RearDrumBrakes());

public class Car
{
    public BrakeType TypeOfBrake {get; set;}

    public void Brake()
    {
        strategyList[TypeOfBrake].Brake();
    }
}

因此,它不是一个使类逻辑混乱的大型 switch 语句,而是一个简单的字典查找。

【讨论】:

    猜你喜欢
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    相关资源
    最近更新 更多