在 C# 中打开类型时使用 goto 在 switch 中失败

Using goto to fall-through in switch when also switching on type in C#

编辑:我会重新表述这个问题: 是否可以以这种方式使用 switch 语句。似乎一方面允许将类型作为可以简化代码外观的案例,但是如果你想通过使用 go to 语句的 fall-through 来实现重用,那么这是不可能的。目前我对语言结构更感兴趣,而不是实际解决我可以通过重复一些代码或移动到 if else 语句来解决的问题。 我知道 goto 通常是不好的,但它似乎至少可以作为一种在 C 中模拟 fall-through 机制而不会被 using/omitting break 容易出错的方法;一不小心

我想将 switch 语句与切换类型结合使用,但我想使用 goto

来使用 fall-trough

我想根据列表中元素的类型执行不同的操作: 但我收到错误消息:Use of unassigned local variable 'animal1' 我可以使用对象类型上的开关来完成它,还是我需要比较字符串或使用 if-else 结构?

using System;
using System.Collections.Generic;
namespace switch_type_experiments
{
    public class Animal
    {
        public void Eat()
        { }
    }

    public class Mammal : Animal
    {
        public void DoMammalStuff()
        { }
    }

    public class Dog : Mammal
    {
        public void Bark()
        {
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Animal> listOfAnimals = new();

            foreach (Animal animal in listOfAnimals)
            {
                switch (animal)
                {
                    case Dog animal1:

                        //do stuff only applicable for dog such as accessing 
                        // available only for dogs
                        animal1.Bark();
                        goto MammalLabel;

                    case Mammal animal1:
                    MammalLabel:
                        //do Mammal stuff
                        animal1.DoMammalStuff();
                        goto AnimalLabel;


                    case Animal animal1:
                    AnimalLabel:
                        animal1.Eat();
                        //do Animal stuff

                        break;
                    default:
                        break;
                }

            }
        }
    }
}

如果我的理解是正确的,那么您只需 3 行代码即可实现相同的效果,而不是 switchgoto 语句:

foreach (Animal animal in listOfAnimals)
{
    if (animal is Dog dog) dog.Bark();
    if (animal is Mammal mammal) mammal.DoMammalStuff();
    animal.Eat();
}

更新#1:使用switch语句

在 C# 中,您可以调用 breakreturncontinuethrowgoto 来控制 fall-through。

goto 有一个非常特殊的版本,您可以在其中跳转到 case x 而不是预定义的 label x。但有一个警告:x 必须是编译时常量。

因此,如果您坚持使用 switch 语句,那么您可以执行以下操作之一:

int type = animal switch
{
    Dog dog => 3,
    Mammal mammal => 2,
    _ => 1
};

switch (type)
{
    case 3:
        (animal as Dog).Bark();
        goto case 2;
    case 2:
        (animal as Mammal).DoMammalStuff();
        goto case 1;
    case 1:
        animal.Eat();
        break;
}

ImmutableDictionary<Type, int> mapping = new Dictionary<Type, int>
{
    { typeof(Dog), 3 },
    { typeof(Mammal), 2 }
}.ToImmutableDictionary();

int type = mapping.TryGetValue(animal.GetType(), out type) ? type : 1;

switch (type)
{
    case 3:
        (animal as Dog).Bark();
        goto case 2;
    case 2:
        (animal as Mammal).DoMammalStuff();
        goto case 1;
    case 1:
        animal.Eat();
        break;
}