【问题标题】:Whats stopping C# compiler from implementing 'Switch' statement on 'Type'? [duplicate]是什么阻止 C# 编译器在“Type”上实现“Switch”语句? [复制]
【发布时间】:2013-11-24 19:30:33
【问题描述】:

我知道目前的 C# 编译器不允许像这样打开类型

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

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

提前谢谢你。

【问题讨论】:

标签: c# .net compiler-optimization


【解决方案1】:

如果您在谈论原始类型,您可以切换 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;
}

顺便说一句,您可能需要阅读How many Microsoft employees does it take to change a lightbulb?的问题答案@

【讨论】:

  • 之前不知道谢谢
【解决方案2】:

我会向您推荐以下已接受的答案:switch statement in C# and "a constant value is expected"。编译器需要在编译时知道不会有任何重复,因此它只接受常量。顺便说一句,你可以用

达到同样的效果
switch (typeof(MyObj).FullName 

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

case "MyNamespace.Type1":
   /*stuff*/
   break;
case "MyNamespace.Type2":
   /*other stuff*/
   break;
default:
   /*default stuff*/

【讨论】:

  • 类型肯定会在编译时得到评估。
  • 它们在编译时被分析,但它们不是编译时的常量。它们在运行时重新绑定。
【解决方案3】:

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

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() 并打开它。这不是推荐的做法,因为您随后会硬编码允许更改为您的开关的字符串,但您可以这样做。

【讨论】:

  • 我能理解你所说的 Scott,我不能同意更多,我试图重构遗留代码,其中抛出不同的异常并在父级捕获,然后用于发送适当的错误信息。我发现了很多: if (ex is XmlSchemaValidationException) errorCode = ServiceExceptionErrorCode.XmlSchemaValidation; else if (ex is BadRequestException) errorCode = ServiceExceptionErrorCode.BadRequest;老实说,不知道如何清理这个烂摊子。非常感谢您的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多