为什么'='不能在C#中超载?

18 c# operator-overloading

我在想,为什么我不能在C#中重载'='?我能得到更好的解释吗?

Dav*_*eas 31

内存管理语言通常使用引用而不是对象.定义类及其成员时,您正在定义对象行为,但是在创建变量时,您正在使用对这些对象的引用.

现在,operator =应用于引用,而不是对象.当您将引用分配给另一个引用时,实际上将接收引用指向另一个引用所在的同一对象.

Type var1 = new Type();
Type var2 = new Type();

var2 = var1;
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,在堆上创建了两个对象,一个由var1引用,另一个由var2引用.现在,最后一个语句使var2引用指向var1引用的同一对象.在该行之后,垃圾收集器可以释放第二个对象,并且内存中只有一个对象.在整个过程中,不对对象本身应用任何操作.

回到为什么=不能重载,系统实现是你可以用引用做的唯一明智的事情.您可以重载应用于对象的操作,但不能重载参考.

  • @ user492238:`operator =`不是对象的操作,而是对引用的操作.您可以重载应用于*objects*的运算符,但不能重新定义应用于*references*的运算符,在这种特殊情况下,这样做会改变语言的语义:a*reference*type将表现为*值*类型. (6认同)
  • @DavidRodríguez-dribeas 这是一个经常重复的陈述,但它是一个同义反复 - 它重申了事实,但没有提供任何推理。在 C# 中,“operator=”的作用与“static void allocate(ref Type dst, in Type src) { dst = src; }`。我们怎么知道这一点?您可以对 C# 源代码进行机器翻译,并用调用“assign”替换所有赋值(除了“assign”本身中的赋值:),程序将执行相同的操作。哎呀,一切都会内联,并且没有开销(我已经尝试过)。遗憾的是语言并没有揭露这一点。 (3认同)

mar*_*rkt 16

如果你重载了'=',你就永远无法在创建对象引用后更改它....想一想 - 任何对ObjectWithOverloadedOperator的调用=重载运算符内部的某些内容都会导致对重载运算符的另一次调用...那么重载运算符究竟会做什么呢?也许设置一些其他属性 - 或将值设置为新对象(immutability)?一般不是'='暗示..

但是,您可以覆盖隐式和显式强制转换运算符:http: //www.blackwasp.co.uk/CSharpConversionOverload.aspx

  • 使用这样的overloadable =运算符不是用引用所指向的对象做出某些东西,而是"知道"某些东西被分配给变量.这在需要值类型语义和/或立即处置(至少)的场景中很重要. (2认同)

Tom*_*icz 8

因为这样做真的没有意义.

在C#中,为变量赋予对象引用.因此它对变量和对象引用进行操作,而不是对象本身.根据对象类型重载它没有意义.

在C++中,定义operator =对于可以在堆栈上创建实例的类有意义,因为对象本身存储在变量中,而不是对它们的引用.因此,定义如何执行此类分配是有意义的.但即使在C++中,如果你有一组通常通过指针或引用使用的多态类,你通常会明确禁止通过将operator =和copy构造函数声明为private(或继承自boost :: noncopyable)来复制它们,因为与您在C#中重新定义=的原因完全相同.简单地说,如果你有A类的引用或指针,你真的不知道它是指向A类的实例还是B类的子类.所以你真的知道如何在这种情况下执行=吗?


pyo*_*yon 7

实际上,operator =如果你可以定义具有值语义的类并在堆栈中分配这些类的对象,那么重载是有意义.但是,在C#中,你不能.