[英]Odd behaviour change with var, dynamic and linq combination
我(懒惰地)在下面代码的原始版本中使用了var
,并在代码的完全不同的部分得到了一个奇怪的运行时异常。 将“var”更改为“int”修复了运行时异常,但我不明白为什么。 我把代码煮成了这个例子;
public class Program
{
private static List<string> Test(string i) { return new List<string> {i}; }
private static dynamic GetD() { return 1; }
public static void Main()
{
int value1 = GetD(); // <-- int
var result1 = Test("Value " + value1);
// No problem, prints "Value 1", First() on List<string> works ok.
Console.WriteLine(result1.First());
var value2 = GetD(); // <-- var
var result2 = Test("Value " + value2);
// The below line gives RuntimeBinderException
// 'System.Collections.Generic.List<string>' does not contain a
// definition for 'First'
Console.WriteLine(result2.First());
}
}
我可以看到“var”的类型是动态的而不是int,但是为什么该类型传播到并影响对Test()
的调用的返回值的行为?
编辑:也许我应该澄清我的问题; 我可以看到dynamic
传播到result2
,我无法理解为什么,当IDE明确指出List<string> Test(string)
是被调用的方法时,它仍然将返回值推断为动态。 这是IDE比编译器更聪明的情况吗?
您的代码编译如下:
public static void Main()
{
int value1 = GetD(); // <-- int
List<string> result1 = Test("Value " + value1);
// No problem, prints "Value 1", First() on List<string> works ok.
Console.WriteLine(result1.First());
dynamic value2 = GetD(); // <-- var
dynamic result2 = Test("Value " + value2);
// The below line gives RuntimeBinderException
// 'System.Collections.Generic.List<string>' does not contain a
// definition for 'First'
Console.WriteLine(result2.First());
}
result2
是一个动态对象,然后不支持扩展方法(用作扩展方法)。
但是,您可以这样做:
Console.WriteLine(Enumerable.First(result2));
你的IDE不是那么聪明。 尝试添加新方法:
private static List<int> Test(int i) { return new List<int> { i }; }
它将为您提供两种可能性。
C#规范第7.6.5段:
如果至少满足下列条件之一,则动态绑定调用表达式(第7.2.2节):
- primary-expression具有编译时类型dynamic。
- 可选参数列表的至少一个参数具有编译时类型dynamic,而primary-expression没有委托类型。
你可以看到下面的iamge显然可能是什么问题。
结果2的GetType()显示它是动态对象。
此外,dynamic关键字不提供对扩展方法的支持
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.