繁体   English   中英

.NET 4中的奇怪切换行为

[英]Weird switch behavior in .NET 4

我有一个问题,在下面的代码中了解导致编译错误的原因:

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)中的简化版本,它是在将应用程序从VSTO3迁移到VSTO4后出现的,当时VSTO中的一个方法被更改为返回dynamic类型值而不是object

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

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

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

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

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

switch语句的控制类型由switch表达式建立。

  • 如果switch表达式的类型是sbytebyteshortushortintuintlongulongboolcharstringenum-type ,或者如果它是与这些类型之一对应的可空类型,那么这就是switch语句的管理类型。
  • 否则,从switch表达式的类型到以下可能的控制类型之一,必须存在一个用户定义的隐式转换(第6.4节): sbytebyteshortushortintuintlongulongcharstring或者,对应于这些类型之一的可空类型。
  • 否则,如果不存在此类隐式转换,或者如果存在多个此类隐式转换,则会发生编译时错误。

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

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

如果你替换:

var test = foo(x);

有:

string test = foo(x);

这一切都按你所知编写。

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

Switch语句仅支持数字,字符,枚举和字符串。 dynamic不是那些东西。 如果你假设x是一个字符串,你可以将其强制转换:

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

如果不是,你只会得到一个运行时错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM