c# - C#如何处理运算符重载

标签 c# optimization operator-overloading

假设我在 C# 中有一个复数类,其加法运算符定义如下。

public static Complex operator +(Complex c1, Complex c2) 
 {
      return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
 }

并像这样使用。

 Complex c1, c2, c3, c4;

 c1 = new Complex(...)
 ...
 c4 = new Complex(...)

 Complex csum = c1 + c2 + c3 + c4;

现在,我的问题是 C# 编译器+运行时将如何处理这个问题。显然,它看起来会做这样的事情。

 ct1 = c1 + c2; // ct1 is a temporary object created by the compiler
 ct2 = ct1 + c3;
 csum = ct2 + c4;

或者它是否足够聪明,意识到它可以像这样以更好的方式(更少创建新的临时对象)做到这一点。

 ct = c1 + c2;
 ct += c3;
 csum = ct + c4; 

最佳答案

除了为它命名的局部变量外,单个表达式等效于(就生成的代码而言)单独的语句。 JIT 可以优化它,但编译器不能。请注意,如果 Complex 是一个值类型,那么它实际上不会涉及分配对象1

值得注意的是,+运算符在C#中专门为string处理(由语言指定,不在框架本身)正是为了避免这种情况事情:x + y + z 被(或至少可以)转换为 string.Concat(x, y, z) 以避免创建临时字符串。


1 我所说的“对象”指的是一 block 内存区域,带有对象 header (类型引用、同步块(synchronized block)等),后跟字段,分配在堆上,而不是“值类型” value”,它只包含数据本身,可能在堆上,也可能在栈上。堆栈/堆部分是 implementation detail当然,但是一个潜在的重要的...我相信区分“只是一个值类型值”和“一个完整的对象”是合理的。

关于c# - C#如何处理运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9500754/

相关文章:

c++ - 需要帮助优化查找所有可能子字符串的程序

c# - CA 2225 同时重载长运算符

c++ - 在类中初始化可变长度的 C 字符串

java - 数字谜题解决方案的数字平方和可以进一步优化吗?

c++ - 模板化线性代数 vector 类中出现奇怪的 "Member function not viable"错误

c++ - 为什么声明复制构造函数不会删除复制赋值运算符,反之亦然?

c# - 不同范围的属性 - 公共(public) getter 和内部 setter

c# - 尝试将粗体应用于整行但不断获得空引用 - NPOI

C# 向左旋转位溢出问题

c# - LINQ to DataGridViewRowCollection