Home > Software engineering >  How to convert a LINQ statement from VB to C#
How to convert a LINQ statement from VB to C#

Time:01-19

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();
  • Related