C#如何实现params out语法 返回可变数量out参数优化ORM性能
语法错误原因
C#语言规范明确禁止params参数修饰符与out/ref修饰符同时使用,你期望的params out Model[]写法本身不符合语法规则,编译器必然会报错。params的本质是编译阶段将可变数量的入参自动封装为数组传递,而out要求传入变量引用用于返回赋值,二者的实现逻辑天然冲突,不可能通过调整语法实现。
可行高性能解决方案
方案1:多泛型参数重载(完全匹配你的调用写法,零额外开销)
模仿.NET内置Action/Func的实现逻辑,编写不同参数数量的泛型重载,最多写到你需要的参数上限即可(一般ORM场景写到8~16个参数足够覆盖99.9%的使用场景),该方案没有任何数组、列表等IEnumerable类型的堆分配,所有参数直接在栈上传递引用,性能完全符合要求,且调用写法和你示例中的代码完全一致。
示例实现代码:
public class FooDBContext { // 原有代码保持不变 // 1个out参数重载 public bool GetEntities<T1>(out T1 t1) where T1 : Model, new() { t1 = new T1(); SetValues(t1); // 补充赋值成功/失败判断逻辑 return true; } // 2个out参数重载 public bool GetEntities<T1, T2>(out T1 t1, out T2 t2) where T1 : Model, new() where T2 : Model, new() { t1 = new T1(); t2 = new T2(); SetValues(t1, t2); return true; } // 3个out参数重载,后续4~N个参数的重载逻辑完全一致,逐次增加泛型参数即可 public bool GetEntities<T1, T2, T3>(out T1 t1, out T2 t2, out T3 t3) where T1 : Model, new() where T2 : Model, new() where T3 : Model, new() { t1 = new T1(); t2 = new T2(); t3 = new T3(); SetValues(t1, t2, t3); return true; } }
调用代码和你原来的写法完全一致,无需修改:
foreach(var row in a.HasNext()) { a.GetEntities(out Entity1 e1_1, out Entity1 e1_2, out Entity2 e2_1, out EntityN en_1, out Entity2 e2_2); a.GetEntities(out e1_1, out e1_2); }
方案2:值元组返回(C# 7.0+支持,写法更简洁)
如果可以调整调用写法,使用值元组返回结果也能实现零堆分配的高性能返回,且不需要写大量重载的out参数:
// 示例实现 public (bool IsSuccess, T1 E1, T2 E2) GetEntities<T1,T2>() where T1 : Model, new() where T2 : Model, new() { var e1 = new T1(); var e2 = new T2(); SetValues(e1,e2); return (true, e1, e2); } // 调用示例 var (res, e1_1, e1_2) = a.GetEntities<Entity1, Entity1>();
内容的提问来源于stack exchange,提问作者Fabio André
相关产品推荐
相关产品推荐

