[英]Understanding explicit vs implicit variable declaration in LINQ
我有一個名為Item的類,我正在對該類執行LINQ查詢,但是我注意到當我嘗試使用group
運算符時:
我沒有訪問IEnumarable
接口擴展方法(如key
權限。
就像是:
var groupByQuery =
from item in items
group item by item.ItemType[0];
foreach (Item item in groupByQuery)
{
Console.WriteLine(item.Key);
...
}
會產生錯誤:
`Error 1 'ProductCatalog.Item' does not contain a definition for 'Key' and no extension method 'Key' accepting a first argument of type 'ProductCatalog.Item' could be found (are you missing a using directive or an assembly reference?)`
我需要將其更改為:
foreach (var item in groupByQuery)
{
Console.WriteLine(item.Key);
...
}
使它工作。 我只需要了解為什么會發生這種情況,我腦子里有些東西告訴我這與Item
的類型和Key
返回的類型有關,僅此而已。
如果僅item in groupByQuery
行中使用IntelliSense和mouseover item
,則將看到這些類型的區別。
使用var item
將使用由group by表達式生成的類型,即IGrouping<T, Item>
(我在這里寫了T
,因為我不知道ItemType[0]
的類型)。
如您所料,使用Item item
會將其轉換為Item
。 如錯誤所描述,類Item
不實現Key
。 如果選擇這樣做,則可以在班級中明確地執行此操作,但這可能不是最佳方法。 其原因是,通常當使用group by
要返回的一組Item
,這比的單個實例不同Item
(假設將存在多個Items
與ItemType[0]
因此,您可能更喜歡使用實現IGrouping<T, Item>
的新類(例如ItemGroup
)或重新考慮查詢。
組查詢返回一個IEnumerable組。 一個組具有一個鍵和一個IEnumerable。 因此,您的for循環可能是這樣的:
foreach (var group in groupByQuery)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(" {0}", item);
}
}
那么,您的問題更多是關於foreach
。 foreach
似乎等同於for
或while
從第一個元素到最后一個元素(或break
)的索引。 隨着您的foreach (Item item in groupByQuery)
,它似乎開始如下:
Item item = groupByQuery.ElementAt(0);
但是,由於組不是Item類型的,因此無法編譯。
關於foreach
的非直觀(但已完全記錄)的事情是,編譯器將其翻譯為就好像是這樣編碼的:
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
其中V是循環控制變量的給定或隱式類型。 它執行強制轉換,即使您更喜歡編譯器錯誤,它也可能在運行時失敗。 對於非泛型IEnumerable,強制轉換是我們的目的。 實際上,對於IEnumerable<T>
沒有foreach
,它降級為IEnumerable
的foreach
。
如果您想知道為什么,請參閱Eric Lippert的博客 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.