我正在尝试将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 Query和VB.Net - Linq Group By returns IEnumerable(Of Anonymous Type),但是我认为它们并不适用,因为我将直接与小组合作,而不是专门的班级。
为什么这些实现未返回相同的内容,我该怎么做才能使IEnumerable(Of IEnumerable(Of ValidationResult))
成为必需的q
?
答案 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)