如何将多个IncrementalValuesProvider<T>组合为直观的自定义对象?
组合多个IncrementalValuesProvider为自定义对象的方案
完全可以避免嵌套的Left/Right访问,下面是几种实用的方法:
1. 扩展方法封装多参数Combine
直接写扩展方法支持同时组合多个源,一步到位映射到自定义对象,彻底避免中间嵌套:
public static class IncrementalValuesProviderExtensions { public static IncrementalValuesProvider<TResult> CombineInto<T1, T2, T3, TResult>( this IncrementalValuesProvider<T1> source1, IncrementalValuesProvider<T2> source2, IncrementalValuesProvider<T3> source3, Func<T1, T2, T3, TResult> selector) { return source1.Combine(source2.Collect()) .Combine(source3.Collect()) .Select(x => selector(x.Left.Left, x.Left.Right, x.Right)); } } // 使用方式 IncrementalValuesProvider<Combined> combined = one.CombineInto(two, three, (o, t, th) => new Combined { One = o, Two = t, Three = th });
如果需要支持更多参数,可以继续重载扩展方法,固定数量源的场景下,这种方式最直观。
2. 使用命名元组简化中间组合
利用C#命名元组特性,先把多个源组合成元组,再映射到自定义对象,中间步骤的访问会比嵌套Left/Right清晰很多:
IncrementalValuesProvider<Combined> combined = one .Combine(two.Collect()) .Select(x => (One: x.Left, Two: x.Right)) .Combine(three.Collect()) .Select(x => new Combined { One = x.Left.One, Two = x.Left.Two, Three = x.Right });
命名元组让中间对象的属性语义明确,不用反复记忆层级关系。
3. 分步组合拆分逻辑
如果源数量较多,可分步组合,每一步生成包含当前所需属性的匿名对象,逐步构建最终的自定义对象:
// 第一步:组合one和two var oneTwo = one.Combine(two.Collect()) .Select(x => new { One = x.Left, Two = x.Right }); // 第二步:和three组合生成最终对象 IncrementalValuesProvider<Combined> combined = oneTwo.Combine(three.Collect()) .Select(x => new Combined { One = x.Left.One, Two = x.Left.Two, Three = x.Right });
分步写法的好处是逻辑拆分清晰,每一步只处理两个源,不容易搞混层级。
这些方法都能避免反复嵌套访问Left/Right,让代码更易读维护。
内容的提问来源于stack exchange,提问作者Peter Morris
相关产品推荐
相关产品推荐

