EDIT: I would reformulate the question:
Is it at all possible to use switch statement in this way. It seems that on one hand it is allowed to have types as cases which may simplify the look of the code, but then if you want to achieve reuse by falling-through using go to statement then this is not possible. As it currently stands I'm more interested in the language construct than actually solving the problem which I can solve by repeating some code or moving to if else statements.
I know goto is bad in general, but it seems that it is at least acceptable as a way to simulate the fall-through mechanism in C without being error prone to by using/omitting break; by mistake
I would like to use switch statement in conjunction with switching over types, but i want to use fall-trough using goto
I would like to perform different actions depending on the type of the element in the list:
but I get error: Use of unassigned local variable 'animal1' Can I do it using switch on the object type or I need to compare strings or use if-else constructs?
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;
}
}
}
}
}
If my understanding is correct then you can achieve the same with only 3 lines of code instead of switch and goto statements:
foreach (Animal animal in listOfAnimals)
{
if (animal is Dog dog) dog.Bark();
if (animal is Mammal mammal) mammal.DoMammalStuff();
animal.Eat();
}
UPDATE #1: Use switch statement
In C# you can call break, return, continue, throw or goto to control the fall-through.
goto has a really special version where you can jump to a case x rather than a predefined label x. But there is one caveat: the x must be compile time constant.
So, if you stick to use switch statement then you can do one of the following:
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;
}
OR
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;
}