在 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 行代码即可实现相同的效果,而不是 switch
和 goto
语句:
foreach (Animal animal in listOfAnimals)
{
if (animal is Dog dog) dog.Bark();
if (animal is Mammal mammal) mammal.DoMammalStuff();
animal.Eat();
}
更新#1:使用switch
语句
在 C# 中,您可以调用 break
、return
、continue
、throw
或 goto
来控制 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;
}
编辑:我会重新表述这个问题:
是否可以以这种方式使用 switch 语句。似乎一方面允许将类型作为可以简化代码外观的案例,但是如果你想通过使用 go to 语句的 fall-through 来实现重用,那么这是不可能的。目前我对语言结构更感兴趣,而不是实际解决我可以通过重复一些代码或移动到 if else 语句来解决的问题。
我知道 goto
通常是不好的,但它似乎至少可以作为一种在 C 中模拟 fall-through 机制而不会被 using/omitting break
容易出错的方法;一不小心
我想将 switch
语句与切换类型结合使用,但我想使用 goto
我想根据列表中元素的类型执行不同的操作:
但我收到错误消息: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 行代码即可实现相同的效果,而不是 switch
和 goto
语句:
foreach (Animal animal in listOfAnimals)
{
if (animal is Dog dog) dog.Bark();
if (animal is Mammal mammal) mammal.DoMammalStuff();
animal.Eat();
}
更新#1:使用switch
语句
在 C# 中,您可以调用 break
、return
、continue
、throw
或 goto
来控制 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;
}