C# 理解LINQ中显式与隐式变量声明
我有一个名为Item的类,我正在这个类上执行LINQ查询,但我注意到,当我尝试使用C# 理解LINQ中显式与隐式变量声明,c#,linq,C#,Linq,我有一个名为Item的类,我正在这个类上执行LINQ查询,但我注意到,当我尝试使用组操作符时: 我无法访问IEnumarable接口扩展方法,如key 比如: var groupByQuery = from item in items group item by item.ItemType[0]; foreach (Item item in groupByQuery) { Co
组
操作符时:
我无法访问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);
...
}
让它工作。我只需要理解为什么会发生这种情况。我脑海中的某种东西告诉我这与
项的类型有关,类型键返回,但仅此而已。如果您只需在groupByQuery
行中的项的项上使用IntelliSense和鼠标,您将看到这些类型的差异
使用var item
将使用GROUPBY表达式生成的类型,即IGrouping
(我在这里写了T
,因为我不知道ItemType[0]
的类型)
使用Item-Item
将其转换为项
,正如您所期望的那样。如错误所述,类项
未实现键
。如果您选择这样做,您可以在类中显式地这样做,但这可能不是最好的方法。原因是,通常在使用“分组依据”
时,您返回的是一组项
,这与项
的单个实例不同(假设将有多个项
具有项类型[0]
)。因此,您可能更喜欢使用一个新类(例如ItemGroup
)来实现i分组
,或者重新考虑查询。组查询返回组的IEnumerable。组有一个键和一个IEnumerable。因此,您的for循环可以如下所示:
foreach (var group in groupByQuery)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(" {0}", item);
}
}
Item item = groupByQuery.ElementAt(0);
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
你的问题更多的是关于foreach的foreach
似乎相当于for
或从第一个元素到最后一个元素(或break
)的索引。使用您的foreach(groupByQuery中的Item)
,它似乎是这样开始的:
foreach (var group in groupByQuery)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(" {0}", item);
}
}
Item item = groupByQuery.ElementAt(0);
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
但是,由于组不是Item类型,因此无法编译
关于foreach
的一个非直观但完全有文档记录的事情是,编译器将其翻译为如下代码:
foreach (var group in groupByQuery)
{
Console.WriteLine(group.Key);
foreach (var item in group)
{
Console.WriteLine(" {0}", item);
}
}
Item item = groupByQuery.ElementAt(0);
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
其中V是循环控制变量的给定或隐式类型。它执行强制转换,这可能会在运行时失败,即使您希望编译器出现错误。铸造将是我们对非通用IEnumerable的意图。实际上,对于IEnumerable
,没有foreach
,对于IEnumerable
,它将降级为foreach
如果你想知道原因,请看。我已经知道怎么做了,汤姆。我想你需要重新阅读我的问题。