在LINQ的Select方法中对元组进行解构实际会执行什么操作?
错误原因解析
你写的Select语句实际匹配到了LINQ的带索引参数的Select重载,而非你预期的元组解构逻辑,执行逻辑如下:
MathSeeder.GetIntegerSquareRoots()返回的是类型为IEnumerable<(int perfectSquare, int root)>的序列,每个元素是单个值元组对象- 你写的
.Select((perfectSquare, squareRoot) => ...)有两个入参,编译器会优先匹配Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, Int32, TResult>)这个重载:- 第一个参数
perfectSquare会被赋值为整个元组对象,类型是(int, int) - 第二个参数
squareRoot会被赋值为当前元素在序列中的索引,是从0开始递增的int值
- 第一个参数
- 你把这两个值组装成
object[]后,数组第一个元素是元组类型,第二个是int索引,传入测试方法时和声明的两个int入参类型不匹配,自然会抛出异常。
修复方案
两种写法都可以正确完成格式转换:
- 直接访问元组属性(你已经验证过的可行方案)
public static IEnumerable<object[]> PerfectSquareRootData { get; set; } = MathSeeder.GetIntegerSquareRoots() .Select(t => new object[] { t.perfectSquare, t.root }) .ToList();
- 显式解构单个元组参数(需多套一层括号标识是单个参数的解构,不是两个独立入参)
public static IEnumerable<object[]> PerfectSquareRootData { get; set; } = MathSeeder.GetIntegerSquareRoots() .Select(((int perfectSquare, int root) t) => new object[] { t.perfectSquare, t.root }) .ToList();
内容的提问来源于stack exchange,提问作者JansthcirlU
相关产品推荐
相关产品推荐

