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:
Solution 1:
See gjvdkamp's 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.
Solution 2:
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: http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx
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.
Solution 3:
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));
}
Solution 4:
I did it one time with a workaround, hope it helps.
string fullName = typeof(MyObj).FullName;
switch (fullName)
{
case "fullName1":
case "fullName2":
case "fullName3":
}