mat*_*ieu 13 c# linq dynamic c#-4.0
考虑以下(无意义,但仅用于说明目的)测试类:
public class Test
{
public IEnumerable<string> ToEnumerableStrsWontCompile(IEnumerable<dynamic> t)
{
return t.Select(x => ToStr(x));
}
public IEnumerable<string> ToEnumerableStrsWillCompile(IEnumerable<dynamic> t)
{
var res = new List<string>();
foreach (var d in t)
{
res.Add(ToStr(d));
}
return res;
}
public string ToStr(dynamic d)
{
return new string(d.GetType());
}
}
Run Code Online (Sandbox Code Playgroud)
为什么不编译时出现以下错误t.Select(x => ToStr(x))?
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<dynamic>'
to 'System.Collections.Generic.IEnumerable<string>'. An explicit conversion
exists (are you missing a cast?)
Run Code Online (Sandbox Code Playgroud)
第二种方法没有错误.
Jon*_*Jon 11
我相信这里发生的是因为表达式ToStr(x)涉及一个dynamic变量,整个表达式的结果类型也是dynamic; 这就是为什么编译器认为它有一个IEnumerable<dynamic>预期的地方IEnumerable<string>.
public IEnumerable<string> ToEnumerableStrsWontCompile(IEnumerable<dynamic> t)
{
return t.Select(x => ToStr(x));
}
Run Code Online (Sandbox Code Playgroud)
有两种方法可以解决这个问题.
使用显式强制转换:
public IEnumerable<string> ToEnumerableStrsWontCompile(IEnumerable<dynamic> t)
{
return t.Select(x => (string)ToStr(x));
}
Run Code Online (Sandbox Code Playgroud)
这告诉编译器表达式的结果肯定是一个字符串,所以我们最终得到一个IEnumerable<string>.
用方法组替换lambda:
public IEnumerable<string> ToEnumerableStrsWontCompile(IEnumerable<dynamic> t)
{
return t.Select(ToStr);
}
Run Code Online (Sandbox Code Playgroud)
这样编译器会隐式地将方法组表达式转换为lambda.请注意,由于表达式中没有提及dynamic变量x,因此可以立即推断其结果的类型,string因为只有一种方法需要考虑,其返回类型是string.