.NET 4中的奇怪切换行为

时间:2010-06-02 12:54:44

标签: .net .net-4.0 switch-statement

我在解决导致以下代码中的编译错误的原因时遇到问题:

static class Program
{
    static void Main()
    {
        dynamic x = "";
        var test = foo(x);

        if (test == "test")
        {
            Console.WriteLine(test);
        }

        switch (test)
        {
            case "test":
                Console.WriteLine(test);
                break;
        }
    }

    private static string foo(object item)
    {
        return "bar";
    }
}

我得到的错误是switch (test)行:

A switch expression or case label must be a bool, char, string, integral, 
enum, or corresponding nullable type.

Intellisence向我展示foo操作将在运行时解析,这很好,因为我使用动态类型作为参数。但是,我不明白当切换没有时if条件编译得很好。

上面的代码只是我在应用程序(VSTO)中的简化版本,当VSTO中的一个方法更改为返回dynamic类型值而非{{1时,将应用程序从VSTO3迁移到VSTO4后出现}}

任何人都可以给我一个解释是什么问题。我知道如何解决它,但我想了解发生了什么。

5 个答案:

答案 0 :(得分:10)

因为您正在动态调用方法,所以结果也是dynamic(因为返回值可能是任何 - 它直到运行时才知道)。并且switch变量类型不能dynamic

答案 1 :(得分:3)

在编译时,编译器会评估switch表达式的类型。 dynamic的类型在运行时进行评估,因此编译器无法验证它是否(或可转换为)允许的类型之一(根据C# 4 Language Specification是sbyte,byte,short, ushort,int,uint,long,ulong,bool,char,string或enum-type)。

答案 2 :(得分:2)

正如Matt Ellen所说,但有更多的背景。

对于switch语句:来自C#语言规范v4.0:

switch语句的 管理类型 由switch表达式建立。

  • 如果切换表达式的类型为sbytebyteshortushortintuint,{{1 }},longulongboolchar枚举类型,或者如果它是与之对应的可空类型在这些类型中,那就是string语句的管理类型。
  • 否则,从switch表达式的类型到以下可能的管理类型之一,必须存在一个用户定义的隐式转换(第6.4节):switchsbyte,{{1} },byteshortushortintuintlongulong,或者,可空类型对应其中一种类型。
  • 否则,如果不存在此类隐式转换,或者存在多个此类隐式转换,则会发生编译时错误。

对于char语句,表达式被计算为布尔运算。表达式求值被推迟到运行时,因为在变量赋值中的方法调用中使用了string。从上面的规范来看,if看起来需要对交换机类型进行编译时评估。

答案 3 :(得分:0)

这是一些意想不到的行为 - 我本来期望将var设置为显式返回字符串以正确推断字符串类型的方法。哦,好吧.....

如果替换:

var test = foo(x);

使用:

string test = foo(x);

如你所知,这一切都在编译。

这是安全的,因为你已经将foo()声明为返回一个字符串,并且从长远来看可能更直观一些。

答案 4 :(得分:0)

Switch语句仅支持数字,字符,枚举和字符串。 dynamic不是那些东西。如果你假设x是一个字符串,你可以把它投出来:

dynamic x = ""; 
string test = (string)foo(x); 

如果不是,你只会遇到运行时错误。