You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将C# LINQ查询转换为VB.NET时的匿名元组处理问题

C# LINQ到VB.NET的转换问题解答

问题背景

你在将一段查找类成员的C# LINQ代码转VB.NET时,对C#里的命名元组语法不熟悉,尝试用Dictionary实现但无法保留命名标识,想了解是否需要声明私有结构。

原C#代码

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

核心语法说明

C#代码里的(member: m, positions: (user: resolver.GetPosition(m), builtin: i))是命名元组,用来临时封装多组关联值,后续LINQ操作可以直接通过名称访问这些值,无需额外定义类或结构。


解决方案

方案1:使用VB.NET命名元组(推荐,需VB.NET 15+)

VB.NET 15及以上版本支持和C#对应的命名元组语法,直接转换即可保留所有命名标识,逻辑和原C#完全一致:

Dim members = 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()

注意:用OrElse代替Or,和C#的||对应,实现短路逻辑判断,提升性能。

方案2:声明私有结构(兼容旧版VB.NET)

如果你的项目使用不支持ValueTuple的旧版VB.NET,可以声明一个私有结构来封装临时值:

' 先声明私有结构
Private Structure MemberPositionWrapper
    Public Member As MemberInfo
    Public UserPosition As Integer
    Public BuiltinPosition As Integer
End Structure

' 转换后的LINQ查询
Dim members = entityType.GetTypeInfo().GetMembers(bindingFlags)
    .Where(Function(m) m.MemberType = MemberTypes.Property OrElse m.MemberType = MemberTypes.Field)
    .Select(Function(m, i) New MemberPositionWrapper With {
        .Member = m,
        .UserPosition = resolver.GetPosition(m),
        .BuiltinPosition = i
    })
    .Where(Function(x) x.UserPosition <> -1)
    .OrderBy(Function(x) New With {x.UserPosition, x.BuiltinPosition})
    .Select(Function(x) x.Member)
    .ToArray()

这里用匿名类型New With {x.UserPosition, x.BuiltinPosition}模拟原C#中对元组的排序逻辑(元组会按元素顺序依次比较排序)。


关于Dictionary的问题

你之前尝试用Dictionary实现是不合适的:Dictionary是键值对集合,无法同时封装两个命名的数值,而且后续LINQ操作中无法像元组/结构那样直接通过名称访问值,会大幅增加代码复杂度。

内容的提问来源于stack exchange,提问作者G_Hosa_Phat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:41:02