具有动态参数的积分型预期开关的值

时间:2014-02-14 12:58:38

标签: c# exception switch-statement dynamic-variables object-to-string

出于好奇。

如果我有以下代码

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

我收到错误"开关表达式或案例标签必须是bool,char,string,integral,enum或相应的可空类型"

但如果我有以下代码

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

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

2 个答案:

答案 0 :(得分:12)

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

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

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

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

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

查看Format功能的内容,如果您将exception作为object传递,则可以实现相同的功能。如果您使用此功能专门格式化Exceptions,则最好使用Exception作为exception参数的类型。

答案 1 :(得分: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.");
  }

因为交换机无法执行ConvertAction方法中的抛出异常, 这是通过使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.");
  }