为什么我不能在C#中重载+ =运算符?但我仍然可以使用它?

时间:2011-03-05 09:21:58

标签: c# .net operator-overloading

  

可能重复:
  Simple way to overload compound assignment operator in C#?

我正在玩事件,思想事件很奇怪。为什么我不能在泛型类中实现它们。所以我试着发现我不能超载+ =。 From the language specs found here

The overloadable unary operators are:    
+   -   !   ~   ++   --   true   false

The overloadable binary operators are:    
+   -   *   /   %   &   |   ^   <<   >>   ==   !=   >   <   >=   <=

+ =未列出。现在,在你说没有理由重载之前+ =我想提出事实C#有使用+ =运算符的事件以及我试图实现一个有趣的事件并希望使用+ =运算符的事实。现在,我有一种感觉,有人会说这就是为什么事件存在,因为这是唯一的原因。但是我想提出你可以使用+ =与TimeSpan结构。试试吧,var ts= new TimeSpan(); ts += ts;将编译并运行。

我查看了TimeSpan的定义,我不知道它是如何允许的。我看到一个public static TimeSpan operator +(TimeSpan t);看起来很可疑,但后来我意识到它类似于var name = +ts;,就像你可以做var name = -ts;否定一样。

所以我的问题是,我如何使用+ =作为我的结构或类。它似乎得到支持我似乎无法找到它的文档。

4 个答案:

答案 0 :(得分:16)

事件不会使+=-=运算符超载。这只是在C#编译器中硬编码,它将其转换为该事件的添加/删除方法。

您只能重载+-,然后间接过载+=-=。如果您重载+,则自动x += y会重载到x = x + y。因此,对于您的类型,您不需要进行任何额外的工作。只需重载+,您就可以免费获得+=。这当然需要左侧参数和结果类型兼容,但通常情况就是如此。


您不能单独重载+=的原因很可能是它为引用类型创建了奇怪的语义。如果+=修改了左侧的现有实例,则以下代码的行为会很奇怪:

MyClass x=new MyClass();
MyClass y=x;
x+=SomeThing;
y has changed now too

另一方面,+=表示x = x+y,此代码会创建一个新的实例,并将其分配给x。并且原始实例在y中保持不变;


另一方面,在C ++中,可以安全地为+=指定一个单独的重载,因为你可以同时重载赋值和复制构造函数,并使用它来获得正确的语义。

答案 1 :(得分:1)

  

+ =运算符不能重载   直接,但用户定义的类型可以   重载+运算符。

     

使用+ =赋值的表达式   运算符,例如Copy

     

x + = y

     

相当于复制

     

x = x + y

Msdn

答案 2 :(得分:0)

+=只是添加,然后分配的简写。您可以重载+运算符,这也会使+=运算符起作用:

这个编译

class P 
{
    public static P operator +(P rhs, P lhs) {
        return null;
    }   
}

void Main()
{
    P p = new P();
    p += new P();
}

(当然,--=运营商也是如此。

答案 3 :(得分:0)

文档不是谎言。不能使+=运算符超载。

+=运算符只是使用+运算符的快捷方式。像x += y这样的操作被编译器翻译成x = x + y

因此,要更改+=运算符的作用,您必须重载+运算符。