Why doesn't C# switch statement allow using typeof/GetType()?

后端 未结 10 2044
被撕碎了的回忆
被撕碎了的回忆 2020-12-15 08:56

As in this example:

switch ( myObj.GetType ( ) )
{
    case typeof(MyObject):
        Console.WriteLine ( \"MyObject is here\" );
        break;
}

相关标签:
10条回答
  • 2020-12-15 09:07

    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;
    }
    
    0 讨论(0)
  • 2020-12-15 09:08

    a switch in C# only works for integrals or strings. myObj.GetType() returns a Type, which is neither an integral or a string.

    0 讨论(0)
  • 2020-12-15 09:11

    It's that typeof is not a constant and cases must be constants.

    0 讨论(0)
  • 2020-12-15 09:11

    Why don't you just tostring() it?

    0 讨论(0)
  • 2020-12-15 09:12

    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.

    0 讨论(0)
  • 2020-12-15 09:15

    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: ...
    } 
    
    0 讨论(0)
提交回复
热议问题