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 Integer
s), 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?
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()