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

时间:2018-12-27 02:30:58

标签: vb.net linq group-by

我正在尝试将Anthyme Caillard's INotifyDataErrorInfo implementation转换为VB.NET。一切顺利,直到我到达<link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">方法,该方法具有以下LINQ查询,其中Validate的类型为q

IEnumerable<IGrouping<string, ValidationResult>>

我尝试了以下翻译:

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

甚至是lambda表达式版本(假设我正确使用了John Skeet's syntax):

Dim q = From r In valResults
        From m In r.MemberNames
        Group r By r.MemberNames Into Group
        Select Group

但在这两种情况下,Dim q = valResults.GroupBy(Function(r) r, Function(r) r.MemberNames) 的类型均为q

我看过VB and IGrouping for LINQ QueryVB.Net - Linq Group By returns IEnumerable(Of Anonymous Type),但是我认为它们并不适用,因为我将直接与小组合作,而不是专门的班级。

为什么这些实现未返回相同的内容,我该怎么做才能使IEnumerable(Of IEnumerable(Of ValidationResult))成为必需的q

1 个答案:

答案 0 :(得分: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)