I have the following LINQ statement in VB:
Dim query As List(Of RepresentativeCase)
query = (From w In Me.RepresentativeCases
Where w.Active = True
Group w By w.PublicSubType, w.LawArea Into g = Group
Where g.Count(Function(x) x.PublicSubType.Distinct.Count) >= 100
Select g.First()
).ToList()
I am trying to convert into C# and having trouble. I got the following but it doesn't compile:
List<RepresentativeCase> query = (
from w in this.RepresentativeCases
where w.Active == true
group w by new { w.PublicSubType, w.LawArea} into g
let PublicSubType = g.Key.PublicSubType
let LawArea = g.Key.LawArea
where g.Count(x => x.PublicSubType.Distinct().Count()) > 100 // breaks here
select g.First()).ToList();
The where g.Count(x => x.PublicSubType.Distinct().Count()) > 100
line won't compile. Additionally, I am confused by the Into g = Group
in the VB sample - not clear what it does.
What am I missing?
CodePudding user response:
In this line:
Where g.Count(Function(x) x.PublicSubType.Distinct.Count) >= 100
The outer .Count()
method is expecting a lambda that returns a Boolean, where the result tells .Count()
whether or not to include this item as part of the final result. But you have this:
Function(x) x.PublicSubType.Distinct.Count
The result of the above function is an Integer, not a Boolean. Also, you should write it (probably) like this:
Function(x) x.PublicSubType.Distinct().Count()
It is still legal to omit parentheses when calling methods in VB.Net, but this is for backwards compatibility with old code and is not recommended in other situations.
I'm not sure what the VB code is doing here, but with a sane configuration that would not compile in VB, either. What you have is not sane, especially as VB has some weird ideas about what Integer values can map to Boolean true and false.
CodePudding user response:
This:
Where g.Count(Function(x) x.PublicSubType.Distinct.Count) >= 100
would only compile with Option Strict Off
. The outer Count
call requires a delegate that returns a Boolean
, but the inner Count
call is returning an Integer
. That means that that Integer
must be implicitly converted to a Boolean
.
The question you should have been asking was how to fix that VB to compile with Option Strict On
and, to work that out, you should be considering what the code is actually doing. What's actually happening is that a count of zero will be converted to False
and any other count will be converted to True
. That means that what that code is actually doing is determining whether there are any items in the PublicSubType
list. What's the proper way to do that? With the Any
method:
Where g.Count(Function(x) x.PublicSubType.Any()) >= 100
Note that the Distinct
call is pointless because it might change the number of items but not whether there are any items or not.
It should be pretty obvious how to convert that to C# but, so that I am answering the specific question as asked:
List<RepresentativeCase> query = (
from w in this.RepresentativeCases
where w.Active == true
group w by new { w.PublicSubType, w.LawArea} into g
let PublicSubType = g.Key.PublicSubType
let LawArea = g.Key.LawArea
where g.Count(x => x.PublicSubType.Any()) > 100
select g.First()).ToList();