Search code examples
c#vb.netlinqtranslate

Converting C# LINQ query to VB


I'm trying to convert a bit of code from C# to VB.NET that's looking for a specific set of class members and I've got it almost completely worked out except for a little LINQ query that uses some C# syntax with which I'm unfamiliar:

var members = entityType.GetTypeInfo().GetMembers(bindingFlags)
    .Where(m => m.MemberType == MemberTypes.Property || m.MemberType == MemberTypes.Field)
    .Select((m, i) => (member: m, positions: (user: resolver.GetPosition(m), builtin: i)))
    .Where(x => x.positions.user != -1)
    .OrderBy(x => x.positions)
    .Select(x => x.member)
    .ToArray();

The first .Where() bit makes sense and converts to:

.Where(Function(m) m.MemberType = MemberTypes.Property Or m.MemberType = MemberTypes.Field)

But, it's the first .Select() piece that I don't understand. It seems to be defining some labels (or perhaps a temporary structure of some sort) that it can pass along to the next .Where() clause. I've tried to define a function where I declare some variables with these names, but I can't figure out how to declare them:

.Select(Function(m, i)
            Dim member = m
            Dim positions As New Dictionary(Of Integer, Integer)(Resolver.GetPosition(m), i)
        End Function)

The types should be correct (both Integers), but obviously the attempt to just create a Dictionary(Of Integer, Integer) doesn't give me the ability to move into the next .Where() or the .OrderBy() clauses with the "names"/labels for user and builtin propegating.

Do I need to create/declare a Private Structure or something in the class that I can use in that query?


Solution

  • The syntax for initializing named tuples is slightly different in VB.NET:

    Dim members As MemberInfo() = entityType.GetTypeInfo().GetMembers(bindingFlags).
        Where(Function(m) m.MemberType = MemberTypes.Property OrElse m.MemberType = MemberTypes.Field).
        Select(Function(m, i) (member:=m, positions:=(user:=resolver.GetPosition(m), builtin:=i))).
        Where(Function(x) x.positions.user <> -1).
        OrderBy(Function(x) x.positions).
        Select(Function(x) x.member).
        ToArray()