C# switch on type [duplicate]

Possible Duplicate:
C# - Is there a better alternative than this to 'switch on type'?

C# doesn't support switching on the type of an object.
What is the best pattern of simulating this:

switch (typeof(MyObj)) case Type1: case Type2: case Type3: 
10

5 Answers

See another answer; this feature now exists in C#


I usually use a dictionary of types and delegates.

var @switch = new Dictionary<Type, Action> { { typeof(Type1), () => ... }, { typeof(Type2), () => ... }, { typeof(Type3), () => ... }, }; @switch[typeof(MyType)](); 

It's a little less flexible as you can't fall through cases, continue etc. But I rarely do so anyway.

7

Update: This got fixed in C# 7.0 with pattern matching

switch (MyObj) case Type1 t1: case Type2 t2: case Type3 t3: 

Old answer:

It is a hole in C#'s game, no silver bullet yet.

You should google on the 'visitor pattern' but it might be a little heavy for you but still something you should know about.

Here's another take on the matter using Linq:

Otherwise something along these lines could help

// nasty.. switch(MyObj.GetType().ToString()){ case "Type1": etc } // clumsy... if myObj is Type1 then if myObj is Type2 then 

etc.

13

There is a simple answer to this question which uses a dictionary of types to look up a lambda function. Here is how it might be used:

var ts = new TypeSwitch() .Case((int x) => Console.WriteLine("int")) .Case((bool x) => Console.WriteLine("bool")) .Case((string x) => Console.WriteLine("string")); ts.Switch(42); ts.Switch(false); ts.Switch("hello"); 

There is also a generalized solution to this problem in terms of pattern matching (both types and run-time checked conditions):

var getRentPrice = new PatternMatcher<int>() .Case<MotorCycle>(bike => 100 + bike.Cylinders * 10) .Case<Bicycle>(30) .Case<Car>(car => car.EngineType == EngineType.Diesel, car => 220 + car.Doors * 20) .Case<Car>(car => car.EngineType == EngineType.Gasoline, car => 200 + car.Doors * 20) .Default(0); var vehicles = new object[] { new Car { EngineType = EngineType.Diesel, Doors = 2 }, new Car { EngineType = EngineType.Diesel, Doors = 4 }, new Car { EngineType = EngineType.Gasoline, Doors = 3 }, new Car { EngineType = EngineType.Gasoline, Doors = 5 }, new Bicycle(), new MotorCycle { Cylinders = 2 }, new MotorCycle { Cylinders = 3 }, }; foreach (var v in vehicles) { Console.WriteLine("Vehicle of type {0} costs {1} to rent", v.GetType(), getRentPrice.Match(v)); } 

I have used this form of switch-case on rare occasion. Even then I have found another way to do what I wanted. If you find that this is the only way to accomplish what you need, I would recommend @Mark H's solution.

If this is intended to be a sort of factory creation decision process, there are better ways to do it. Otherwise, I really can't see why you want to use the switch on a type.

Here is a little example expanding on Mark's solution. I think it is a great way to work with types:

Dictionary<Type, Action> typeTests; public ClassCtor() { typeTests = new Dictionary<Type, Action> (); typeTests[typeof(int)] = () => DoIntegerStuff(); typeTests[typeof(string)] = () => DoStringStuff(); typeTests[typeof(bool)] = () => DoBooleanStuff(); } private void DoBooleanStuff() { //do stuff } private void DoStringStuff() { //do stuff } private void DoIntegerStuff() { //do stuff } public Action CheckTypeAction(Type TypeToTest) { if (typeTests.Keys.Contains(TypeToTest)) return typeTests[TypeToTest]; return null; // or some other Action delegate } 
0

I did it one time with a workaround, hope it helps.

string fullName = typeof(MyObj).FullName; switch (fullName) { case "fullName1": case "fullName2": case "fullName3": } 
9

You Might Also Like