[英]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.