如何直接为double类型除法运算符创建委托?
问题
在C#中,double类型的除法运算可直接通过x / y实现,其底层会调用double.op_Division方法(接收两个double参数并返回double结果)。尝试直接将该方法赋值给Func<double, double, double>委托时会触发编译错误:
System.Func<double, double, double> d = double.op_Division;
目前仅能通过中间lambda表达式间接实现:
System.Func<double, double, double> d = (double x, double y) => x / y;
但这种方式不够简洁,且担心在高性能场景下存在额外开销,想了解是否有无需中间函数即可直接绑定除法运算符的方法。
解答
可以通过反射或Delegate.CreateDelegate的方式直接绑定底层运算符方法,无需中间lambda包装。
方法1:使用Delegate.CreateDelegate
通过反射获取op_Division的方法信息,再直接创建委托:
var divisionMethod = typeof(double).GetMethod("op_Division", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); System.Func<double, double, double> d = (System.Func<double, double, double>)System.Delegate.CreateDelegate(typeof(System.Func<double, double, double>), divisionMethod);
这种方式直接绑定到底层运算符方法,不会产生额外包装开销。
方法2:使用表达式树
通过表达式树构建除法运算逻辑,编译后生成的委托同样直接指向op_Division:
var paramX = System.Linq.Expressions.Expression.Parameter(typeof(double), "x"); var paramY = System.Linq.Expressions.Expression.Parameter(typeof(double), "y"); var divisionExpr = System.Linq.Expressions.Expression.Divide(paramX, paramY); var d = System.Linq.Expressions.Expression.Lambda<System.Func<double, double, double>>(divisionExpr, paramX, paramY).Compile();
编译后的委托性能与直接调用x / y完全一致,无中间层损耗。
直接赋值失败的原因
C#语法层面不会暴露CLR级别的运算符特殊方法名(如op_Division),因此无法直接通过名称引用该方法,必须通过反射或表达式树间接获取。
关于性能的补充说明
- 反射创建委托、表达式树编译均为一次性操作,后续调用委托的性能与直接使用
x / y完全相同。 - 你之前使用的lambda表达式,在Release模式下会被编译器自动优化为直接调用
op_Division,实际不存在额外性能损耗,无需过度担心。
内容的提问来源于stack exchange,提问作者Brendan Lynn
相关产品推荐
相关产品推荐

