Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解LINQ中显式与隐式变量声明_C#_Linq - Fatal编程技术网

C# 理解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

我有一个名为Item的类,我正在这个类上执行LINQ查询,但我注意到,当我尝试使用
操作符时:

我无法访问
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


如果你想知道原因,请看。

我已经知道怎么做了,汤姆。我想你需要重新阅读我的问题。