簡體   English   中英

當我將.toList添加到linq查詢的末尾時,為什么我只能訪問匿名類型的屬性

[英]why can I only access the properties of an anonymous type when I add .toList to the end of my linq query

我正在學習LINQ和VB,只花了一個小時試圖訪問linq查詢中定義的匿名類型的字段。 關鍵(我學到的)是嘗試使用for循環迭代它之前將查詢轉換為列表。 如何在C#中訪問匿名類型的屬性?

這不起作用: 編輯 (這個編譯,但智能感知不識別類型)

Dim varbl=from itm in collct select New With {.n=itm.Name} 'query here
for each returnedItem in varbl 
     returnedItem.n 'intellisense does not pick up the property names
next 

但這樣做:

Dim varbl=(from itm in collct select New With {.n=itm.Name}).toList
for each returnedItem in varbl 
     returnedItem.n 'this works
next 

有人可以解釋為什么/發生了什么? 上面的(有用的!)帖子只是說它是“由於編譯器的工作方式,一旦你創建了列表,那么下面也應該工作,因為匿名類型具有相同的結構,所以它們也是相同的類型。雖然“我沒有編譯器來驗證這一點”

好吧,我不會回答,因為我的VB非常生疏並且已經過時了(呃,大約十年前的VB6)。 但從.NET的角度來看,這似乎有些不對勁。

您對所鏈接答案的解讀(IMO的解釋不完整)是錯誤的。 這不是你需要將匿名對象放入一個列表中,而是那個已經將它放入List<object> ,這意味着編譯器無法分辨它具有哪些屬性(它處理的是一個object而不是一個有問題的匿名類型的object ,而object沒有Checked屬性)。

無論如何。 我嘗試將您的初始嘗試寫入某些C#中:

private class TestType
{
  public string Name{get;set;}
  public TestType(string name)
  {
    this.Name = name;
  }
}
public static void Main()
{
  TestType[] collct = new TestType[]{new TestType("abc"), new TestType("def"), new TestType("xyz")};
  var varbl = from itm in collct select new {n = itm.Name};
  foreach(var returnedItem in varbl)
    Console.WriteLine(returnedItem.n);
}

然后我在反射器中編譯和反編譯為VB.NET,其中我的Main為:

Public Shared Sub Main()
    Dim collct As TestType() = New TestType() { New TestType("abc"), New TestType("def"), New TestType("xyz") }
    Dim varbl = (From itm In collct Select New With { _
        .n = itm.Name _
    })
    Dim returnedItem
    For Each returnedItem In varbl
        Console.WriteLine(returnedItem.n)
    Next
End Sub

這看起來很像你的原創,不是嗎?

嗯,它有效; 它編譯並運行並給我正確的答案。

我唯一能想到的是,也許IntelliSense在這里沒有出現。 我發現在過去的某些時候,IntelliSense很難建議匿名類型的屬性名稱,雖然我使用SharpDevelop來編寫C#而不是VB(在你使用的任何IDE中),這可能就是這種情況 - 你實際上一直有正確的代碼,但IntelliSense沒有意識到這一點。

在一天結束時,IntelliSense非常好,但它不是編譯器,並且它不能花費盡可能多的資源來做編譯器,因為我們打字的時候會降低我們的速度。

順便說一句,你應該調用ToList ,除非你真的需要為你的目的的列表。 想象一下,如果collct是一個collct加載的枚舉,它會在從數據庫或文件加載東西的背面返回數千個對象。

如果你沒有調用ToList ,那么一旦第一個數據的數據到達,你就會開始迭代它們,而你只需要一次使用少量內存。

如果您確實調用了ToList ,那么程序將停留在該行,直到它將每個對象加載到內存中的大量列表中,然后才啟動For Each

當然,有時你需要能夠通過列表前后移動,或者在迭代之前知道計數,然后調用ToList肯定比繼續重復For Each更好,但是如果你不知道你需要它,不要使用它。

暫無
暫無

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

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