我在解决导致以下代码中的编译错误的原因时遇到问题:
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后出现}}
任何人都可以给我一个解释是什么问题。我知道如何解决它,但我想了解发生了什么。
答案 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表达式建立。
sbyte
,byte
,short
,ushort
,int
,uint
,{{1 }},long
,ulong
,bool
,char
或枚举类型,或者如果它是与之对应的可空类型在这些类型中,那就是string
语句的管理类型。switch
,sbyte
,{{1} },byte
,short
,ushort
,int
,uint
,long
,ulong
,或者,可空类型对应其中一种类型。对于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);
如果不是,你只会遇到运行时错误。