10

只是出于好奇。

如果我有以下代码

public static string Format(dynamic exception)
{
    switch (exception.GetType().ToString())
    {
        case "test":
            return "Test2";
    }
    return null;
}

我收到错误“开关表达式或案例标签必须是布尔、字符、字符串、整数、枚举或相应的可空类型”

但如果我有以下代码

public static string Format(dynamic exception)
{
    string test = exception.GetType().ToString();
    switch (test)
    {
        case "test":
            return "Test2";
    }
    return null;
}

一切都编译得很好。如果 switch 正在检查 Type string 和 ToString() 的变量,有什么区别?还是因为在调用 ToString() 之前有机会抛出异常?

4

2 回答 2

13

我认为问题在于您的exception变量是一个dynamic对象。由于它是动态的,它的类型在编译时不会被解析,也不会在它上面调用任何方法的类型。

因此,第一种情况下的 switch 语句不知道.GetType()方法将返回什么类型或.ToString()方法。如果你想让它工作,你可以像这样投射它:

switch (exception.GetType().ToString() as string)

在您的第二个代码块中,您明确声明 的结果exception.GetType().ToString()将是一个字符串。在这种情况下,编译器知道传递给 switch 语句的变量的类型。

就异常而言:编译器并不关心您的方法调用是否可能引发异常。如果是这样,异常将从 switch 语句中冒出来并从您的方法调用中抛出。

查看Format函数的内容,如果exceptionobject. 如果您使用此函数Exceptions专门格式化,则最好将Exception其用作exception参数的类型。

于 2014-02-14T13:02:44.083 回答
2

我在重构一个方法后发现了这个问题,发现同样的错误,

除了 Jon Senchya 提供的答案之外,我还得到了从如下方法返回的开关值

  var action = Utilities.ConvertAction(x.action);
  switch (action)
  {
            case GridActions.ADD:
              MethodX();
              break;
            case GridActions.UPDATE:
              MethodX();
              break;
            case GridActions.DELETE:
              MethodX();
              break;
            default: throw new WebException("Invalid action.");
  }

因为在ConvertActionswitch 不会执行的方法中有一个 throw 异常,所以通过硬类型化解决了action这个错误:

  GridActions action = Utilities.ConvertAction(x.action);
  switch (action)
  {
            case GridActions.ADD:
              MethodX();
              break;
            case GridActions.UPDATE:
              MethodX();
              break;
            case GridActions.DELETE:
              MethodX();
              break;
            default: throw new WebException("Invalid action.");
  }
于 2014-10-23T09:29:45.343 回答