使用Group By LINQ语句时,VB.NET返回IEnumerable(Of IEnumerable(Of T))。

3

我正在尝试将Anthyme Caillard的INotifyDataErrorInfo实现转换为VB.NET。一切都进行得很顺利,直到我到达Validate方法,其中包含以下LINQ查询,其中q的类型为IEnumerable<IGrouping<string, ValidationResult>>

var q = from r in validationResults
        from m in r.MemberNames
        group r by m into g
        select g;

我尝试了以下翻译:
Dim q = From r In valResults
        From m In r.MemberNames
        Group r By r.MemberNames Into Group
        Select Group

甚至可以使用lambda表达式版本(假设我正确使用了John Skeet的语法):

Dim q = valResults.GroupBy(Function(r) r, Function(r) r.MemberNames)

但在这两种情况下,q 的类型均为 IEnumerable(Of IEnumerable(Of ValidationResult))
我查看了VB 和 IGrouping 用于 LINQ 查询以及VB.Net - Linq Group By 返回 IEnumerable(Of Anonymous Type),但我认为它们并不适用于我的情况,因为我将直接使用该组,而不是一个特定的类。
为什么这些实现没有返回相同的结果,我该怎么做才能使 q 成为所需的 IEnumerable(Of IGrouping(Of String, ValidationResult))
1个回答

2
似乎VB编译器对LINQ查询语法的处理与C#编译器不同。
在C#中,表达式
from element in list
group element by element.Value

等同于

list.GroupBy(element => element.Value)

在VB中,然而。
From element In list
Group element By element.Value Into g = Group

被翻译成

list.GroupBy(Function(element) element.Value,
             Function(key, element) New With { Key .Value = key, Key .g = element })

我不知道VB编译器为什么要在这里引入匿名类型,但事实就是如此。

我建议您始终将C# LINQ查询语法(from a in list select a.Value)转换为方法链(list.Select(a => a.Value))。这样VB编译器就无法干扰。它被强制使用确切的方法链。

然而,你对原始查询的翻译并不正确。

var q = from r in validationResults
        from m in r.MemberNames
        group r by m into g
        select g;

实际上被翻译成

var q = validationResults.SelectMany(r => r.MemberNames, (r, m) => new { r, m })
                         .GroupBy(t => t.m, t => t.r);

在VB中,变为:

Dim q = validationResults.SelectMany(Function(r) r.MemberNames,
                                     Function(r, m) New With { Key .r = r, Key .m = m }) _
                         .GroupBy(Function(t) t.m, Function(t) t.r)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接