2009-11-26 106 views
0

在重載操作符上返回一個新對象似乎是唯一要做的事情。對?C#優化重載操作符

  • 如果你有一個類(X),其中包含一個大的緩衝區緩存的
  • 部分包含的內容,剩下的是自由。
  • 通過創建一個包含兩個操作數的附加內容的新對象,您已經重載了二元+運算符來合併兩個對象(相同類型)。

換句話說:

z = x + y // z is a new object containing the appended data from x and y. 

這顯然是一件好事,因爲我們不希望在操作過程中裂傷x或y。然而,C#語言規範7.2.2說:

當二元運算符重載,相應的賦值運算符(如果有的話)也被隱式重載。

這意味着:

x += y; // will create a new x, copy contents of old x merged with y 
     // and the old x will be garbage collected at some point 

這是痛苦的,因爲它可能會更快只是y的內容複製在X的免費部分。這樣我們就不會複製一個大對象,併爲好垃圾收集器的人留下一個混亂。

我意識到這可以用簡單的x.Add(y)來完成。我很好奇,如果有一種方法可以使用運營商。例如找出我們在賦值運算符中並執行優化的例程。

回答

3

我個人很喜歡C#如何實現這一點。

它更 「顯而易見」 的是:

x += y; 

x = x + y; 

應該有相同的行爲。在C#中,這是強制執行的。由於單獨的過載,人們可能會濫用操作員並阻止操作人員採取相同的行動。

perf差異將會非常小,這也使得它更容易實現和維護,所以我非常喜歡C#方法。

+0

你是對的從形式語言的角度來看,這兩者應該完全一樣。雖然,我不確定是否有或應該有任何方法來優化這些場景。 – MandoMando 2009-11-26 17:51:53

0

所有數學二元運算符都會返回一個新對象。例如。你不希望2 + 3只是因爲你添加它們而將它們中的一個的值改爲五。換句話說,所討論的操作符的語義是非常明確的,並且通過規範來執行。如果你想要不同的東西,你將不得不做出不同的東西:)。我個人比較喜歡它與C++比較,你可以使超載這樣的A = B = C可能導致C被刪除,B被取消分配和A等於任何值,而不考慮C或B