[英]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表达式建立。
sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, bool
, char
, string
或enum-type ,或者如果它是与这些类型之一对应的可空类型,那么这就是switch
语句的管理类型。 sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
, string
或者,对应于这些类型之一的可空类型。 对于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.