switch-case-if 或 if-switch-case

switch-case-if or if-switch-case

我正在与设计师合作开发一个应用程序,其中可以调整一些形状项目的大小。要仅在一种 '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)。我的应用程序应该使用哪个?

请注意,您也可以在开关中使用类型模式。所以你实际上并不需要 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);

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

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

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();
            }
        }
    }
}