4

我知道 C# 编译器目前不允许像

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

有一些解决方案可以使用类型和动作字典或静态类(链接),但我只是好奇,为什么这是一种不好的做法或尚未在编译器中实现?

先感谢您。

4

3 回答 3

1

如果您在谈论原始类型,则可以 switch over TypeCode

var typeCode = Type.GetTypeCode(type);    
switch (typeCode)
{
    case TypeCode.Empty:
        break;
    case TypeCode.Object:
        break;
    case TypeCode.DBNull:
        break;
    case TypeCode.Boolean:
        break;
    case TypeCode.Char:
        break;
    case TypeCode.SByte:
        break;
    case TypeCode.Byte:
        break;
    case TypeCode.Int16:
        break;
    case TypeCode.UInt16:
        break;
    case TypeCode.Int32:
        break;
    case TypeCode.UInt32:
        break;
    case TypeCode.Int64:
        break;
    case TypeCode.UInt64:
        break;
    case TypeCode.Single:
        break;
    case TypeCode.Double:
        break;
    case TypeCode.Decimal:
        break;
    case TypeCode.DateTime:
        break;
    case TypeCode.String:
        break;
}

顺便说一句,您可能需要阅读您可能需要阅读的问题的答案更换灯泡需要多少 Microsoft 员工?

于 2013-11-12T15:15:14.917 回答
1

我会向您推荐以下已接受的答案:C# 中的 switch 语句和“需要一个常量值”。编译器需要在编译时知道不会有任何重复,因此它只接受常量。顺便说一句,你可以达到同样的效果

switch (typeof(MyObj).FullName 

并使用每种类型的名称作为案例条件,例如:

case "MyNamespace.Type1":
   /*stuff*/
   break;
case "MyNamespace.Type2":
   /*other stuff*/
   break;
default:
   /*default stuff*/
于 2013-11-12T15:15:53.740 回答
1

你什么时候会使用开启类型?我能想到的大多数情况都可以通过继承更好地解决,即,而不是这样做:

switch (typeof(MyObj)) {
    case Type1: doSomethingForType1; break;
    case Type2: doSomethingForType2; break;
    case Type3: doSomethingForType3; break;

您将以更加面向对象的方式进行设置:

Interface ISpecialType {
    void doSomething();
}
Type1 : ISpecialType {
    doSomething() {}
}
Type2 : ISpecialType {
    doSomething() {}
}
Type3 : ISpecialType {
    doSomething() {}
}

然后,无论如何,您只需调用MyObj.doSomething(); 它,一开始就多输入一点,但更健壮。

此外,如果打开对您来说真的很重要,您可以随时使用 typeof(MyObj).toString() 并打开它。这不是推荐的做法,因为您将硬编码允许更改为您的开关的字符串,但您可以这样做。

于 2013-11-12T15:18:39.850 回答