As in this example:
switch ( myObj.GetType ( ) )
{
case typeof(MyObject):
Console.WriteLine ( \"MyObject is here\" );
break;
}
In C# 7.0 you can do it. See Pattern Matching in C# 7.0 Case Blocks
// ----- Assume that spaceItem is of type SpaceType,
// and that Planet and Star derive from SpaceType.
switch (spaceItem)
{
case Planet p:
if (p.Type != PlanetType.GasGiant)
LandSpacecraft(p);
break;
case Star s:
AvoidHeatSource(s);
break;
case null:
// ----- If spaceItem is null, processing falls here,
// even if it is a Planet or Star null instance.
break;
default:
// ----- Anything else that is not Planet, Star, or null.
break;
}
a switch in C# only works for integrals or strings. myObj.GetType() returns a Type, which is neither an integral or a string.
It's that typeof is not a constant and cases must be constants.
Why don't you just tostring() it?
The problem is that switch
(per the spec) only works with primitives (int etc) and strings. But yes, it would be nice to have F#-style matching.
From §8.7.2:
switch-label: case constant-expression : default :
... The governing type of a switch statement is established by the switch expression. If the type of the switch expression is sbyte, byte, short, ushort, int, uint, long, ulong, char, string, or an enum-type, then that is the governing type of the switch statement. Otherwise, exactly one user-defined implicit conversion (§6.4) must exist from the type of the switch expression to one of the following possible governing types: sbyte, byte, short, ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if more than one such implicit conversion exists, a compile-time error occurs.
It is obvious, however, that working with such a restricted set allows for simple (and efficient) IL. Note that string
is handled via a dictionary map to an integer.
Second on Peter Hallam's post; it's a great explanation.
You can use TypeCode to work with simple types, though.
switch (Type.GetTypeCode(myObj.GetType())) {
case TypeCode.Boolean: ...
case TypeCode.Char: ...
case TypeCode.String: ...
case TypeCode.Object: ...
default: ...
}