switch-case-if 或 if-switch-case

时间:2021-05-10 12:17:30

标签: c# if-statement switch-statement

我正在与设计师合作开发一款应用,该应用可以调整一些形状项目的大小。要仅在一种“ResizeThumb”类型中调整不同形状的大小,我有以下两个程序:

switch(Mode)
{
    case Mode.CircleCenter:
        if (item is Circle circle1)
        {
            // ...
        }
        break;

    case Mode.CircleRadius:
        if (item is Circle circle2)
        {
            // ...
        }
        break;

    case Mode.RectTopLeft:
        if (item is MyRect rect1)
        {
            // ...
        }
        break;

    // many cases...

    default: break;
}

if (item is Circle circle)
{
    switch (Mode) // just 2 cases
    {
        case Mode.CircleCenter:     
            // ...
            break;
        case Mode.CircleRadius:     
            // ...
            break;
        default: break;
    }       
}
else if (item is MyRect rect)
{
    switch (Mode)
    {
        case Mode.RectTopLeft:      
            // ...
            break;          
        // 8 cases of every border and corner
        default: break;
    }       
}
else if (item is MyEllipse ellipse)
{
    switch (Mode) { /* 8 cases of every border and corner */ }
}
else if (item is Line ellipse)
{
    switch (Mode) { /* 2 cases of every endpoint */ }
}
else
{
    // No Code
}

当我有很多形状要调整大小时,哪个会更快更稳定?似乎第一个会更快,但我不确定。第二个将简单方便(无需使用rect1, rect2 , ... ,rect8)。应该在我的应用中使用哪个?

2 个答案:

答案 0 :(得分:2)

请注意,您也可以在开关中使用类型模式。所以你实际上并不需要 if-else。

switch (item)
{
    case Circle circle:
        ...
    case MyRect rect:
        ...
    case MyEllipse ellipse:
        ...
    case Line line:
        ...
}

所以你可以嵌套 switch 语句。项目或模式是否嵌套无关紧要。


但是这里出现了另一个问题。你不能让这些动作成为形状的虚拟方法吗?假设您有一个基础对象

public abstract class Shape
{
    public abstract void ResizeThumb(Mode mode);
}

然后你会从这个基本形状导出所有形状

public class Circle : Shape
{
    public override void ResizeThumb(Mode mode)
    {
        switch(Mode)
        {
            case Mode.CircleCenter:
                //TODO: do circle things here
                break;
            case Mode.CircleRadius:
                //TODO: do circle things here
                break;
            case Mode.RectTopLeft:
                //TODO: do circle things here
                break;
            default:
                break;
        }
    }
}

然后就可以调用这个方法了,不用关心item的类型

item.ResizeThumb(mode);

此外,我不确定为什么必须针对不同的形状以不同的方式调整拇指大小。通过应用坐标变换,您可以以相同的方式调整每个形状的大小。

答案 1 :(得分:1)

我怀疑您不应该使用开关,也不应该测试对象类型。这是面向对象语言中多态性的经典例证。您的代码应如下所示。

namespace ConsoleApplication1
{
    abstract class Shape
    {
        abstract public void ResizeThumb();
    }

    class Circle : Shape
    {
        public override void ResizeThumb() {
            // Your code to resize a circular thumbnail goes here
        }
    }

    class Ellipse : Shape
    {
        public override void ResizeThumb() {
            // Your code resize an elliptical thumbnail goes here
        }
    }
    class Rectangle : Shape
    {
        public override void ResizeThumb() {
            // Your code to resize a rectangular thumbnail goes here
        }
    }

    class Program
    {
        public void Main() {

            // Create a collection of shapes.
            Shape[] shapes = new Shape[] {
                new Circle(),
                new Ellipse(),
                new Rectangle(),
            };

            // Resize each shape's thumbnail.
            foreach(Shape shape in shapes) {
                shape.ResizeThumb();
            }
        }
    }
}