2013-08-05 68 views
2

假設有一個8-16字節的結構Foo。它有一個靜態方法來將Add()的所有值賦給另一個結構,並且性能是最重要的。我見過許多靜態方法,像下面這樣:靜態方法應該修改一個對象還是返回一個新對象

public static Foo Add(Foo fooA, Foo fooB) 
{ 
    var newVar = fooA.Var + fooB.Var 
    return new Foo(newVar); 
} 

我測量,它可以製成僅引用參數更快:

public static Foo Add(ref Foo fooA, ref Foo fooB) 
{ 
    var newVar = fooA.Var + fooB.Var; 
    return new Foo(newVar); 
} 

很公平。但是它會混淆如果我避免創建一個新的實例,而是修改第一個參數?

public static void Add(ref Foo fooA, ref Foo fooB) 
{ 
    fooA.Var += fooB.Var; 
} 

我一直沒能雄辯,我想制定我的問題,但我希望這可以理解。

編輯: 或者,如果需要這樣的東西,該方法不應該是靜態的。這是一個正確的斷言嗎?

回答

0

你的第二個例子肯定會更快,因爲.net框架不會像你在「byval」時那樣複製你的參數。當需要所有類型的性能增益時使用這種技術。很顯然,「byref」比「byval」更快。

您的方法可以是靜態或實例,如果您使用「ref」,則不會複製內存,而在您的情況下,它是一個值類型的結構。

+0

我明白'ref'是什麼。第三種情況是最快的,因爲我避免分配任何額外的內存。我想我的問題是:我應該保持靜態,還是作爲實例方法更好? –

+1

只要對或錯都沒有關係。這一切都取決於你的設計! –

+0

我試圖將我的設計基於人們期望的東西,而不是某種模糊的東西,因此我在這裏問了一個問題。 –

1

這並不令人困惑,但你會得到不同的結果。在第二種情況下,你正在改變其中一個輸入,也許你不想要。

此行爲被稱爲Side effect,有時候這是一種真正的痛苦。這是一個很好的理由,人們會使用函數式編程(更少的副作用)而不是命令式語言。

+0

你的意思是第三種情況,對嗎?第二種情況沒有副作用。 –

+2

對,對不起。我提到第三種情況。這取決於你想要做什麼,但大多數時候修改參數是一個壞主意。 – fanton

相關問題