如何在LINQ查询中返回包含ISketchEntity与ChainMatchType的命名元组
解决方案
标准LINQ合并写法
你可以分别编写三个场景的查询,每个查询直接返回符合要求的命名元组,最后合并结果即可:
// 匹配EndPoint场景 var endMatches = from entity in remainingEntities where entity.EndPoint.FuzzyEqual(matchPoint, _tolerance) select (Entity: (ISketchEntity)entity, MatchType: ChainMatchType.End); // 匹配StartPoint场景 var startMatches = from entity in remainingEntities where entity.StartPoint.FuzzyEqual(matchPoint, _tolerance) select (Entity: (ISketchEntity)entity, MatchType: ChainMatchType.Start); // 匹配CenterPoint场景 var centerMatches = from entity in remainingEntities where entity.CenterPoint.FuzzyEqual(matchPoint, _tolerance) select (Entity: (ISketchEntity)entity, MatchType: ChainMatchType.Center); // 合并所有结果转为目标类型List List<(ISketchEntity Entity, ChainMatchType MatchType)> result = endMatches .Concat(startMatches) .Concat(centerMatches) .ToList();
如果你的sketchEntity已经显式实现了ISketchEntity接口,可以去掉select中的强制类型转换。
高性能优化写法
如果remainingEntities集合体量较大,三次遍历会有额外性能开销,可以改用单次遍历直接生成结果:
List<(ISketchEntity Entity, ChainMatchType MatchType)> result = new(); foreach (var entity in remainingEntities) { if (entity.EndPoint.FuzzyEqual(matchPoint, _tolerance)) { result.Add((entity, ChainMatchType.End)); } if (entity.StartPoint.FuzzyEqual(matchPoint, _tolerance)) { result.Add((entity, ChainMatchType.Start)); } if (entity.CenterPoint.FuzzyEqual(matchPoint, _tolerance)) { result.Add((entity, ChainMatchType.Center)); } }
原写法错误原因
你之前返回(IEnumerable<sketchEntity>, end)的写法,是将整个LINQ查询的返回集合与枚举值打包为了一个顶层元组,而非对集合内的每个元素单独附加枚举标记。正确的逻辑是在select子句中,为每一条匹配到的实体构造独立的命名元组。
内容的提问来源于stack exchange,提问作者Eric Snyder
相关产品推荐
相关产品推荐

