簡體   English   中英

奇數行為隨var,dynamic和linq組合而變化

[英]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比編譯器更聰明的情況嗎?

問題是First是一個擴展方法而不是實例方法,並且運行時綁定器無法動態區分擴展方法和實例方法。

你可以在這里閱讀更多內容:

擴展方法和動態對象

您的代碼編譯如下:

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));

UPDATE

你的IDE不是那么聰明。 嘗試添加新方法:

private static List<int> Test(int i) { return new List<int> { i }; }

它將為您提供兩種可能性。

UPDATE2

C#規范第7.6.5段:

如果至少滿足下列條件之一,則動態綁定調用表達式(第7.2.2節):

  • primary-expression具有編譯時類型dynamic。
  • 可選參數列表的至少一個參數具有編譯時類型dynamic,而primary-expression沒有委托類型。

你可以看到下面的iamge顯然可能是什么問題。

GetType()值

結果2的GetType()顯示它是動態對象。

此外,dynamic關鍵字不提供對擴展方法的支持

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM