2013-04-23 98 views
5

更好假設我有以下組中的靜態函數這是在這種情況下,返回或ref

在這裏,我通過引用發送的變量:

public static void ProcessEmailMessage(ref string HTML) 
     { 
      ModifyLinks(ref HTML); 
      AddFakeImage(ref HTML); 
     } 

     public static void ModifyLinks(ref string HTML) 
     { 
      //modify HTML links 
     } 


     public static void AddFakeImage(ref string HTML) 
     { 
      //adds an image to the HTML 
     } 

和在這裏,我通過值

發送的可變
public static string ProcessEmailMessage(string HTML) 
     { 
      HTML = ModifyLinks(HTML); 
      HTML = AddFakeImage(HTML); 
      return HTML; 
     } 

     public static string ModifyLinks(string HTML) 
     { 
      //modify HTML links 
      return HTML; 
     } 


     public static string AddFakeImage(string HTML) 
     { 
      //adds an image to the HTML 
      return HTML; 
     } 

哪一個更有意義,2是否有任何性能差異?

+2

** b)** ......... – I4V 2013-04-23 17:42:23

回答

8

如果可能,避免使用out和ref參數。

使用ref和out參數的方法更難以使用,您需要聲明一個變量來保存結果,並且語義有點難以理解。性能差異(如果有的話)可以忽略不計。

在這種情況下,Visual Studio中的代碼分析可能會發出警告。

有關更詳細的說明,請參閱http://msdn.microsoft.com/en-us/library/ms182131

+1

指向外部文檔的鏈接很好,但您應在此處包含摘要。如果外部鏈接斷開,那麼SO答案仍然有用。 – cdhowie 2013-04-23 17:44:21

+0

@cdhowie:感謝您指出這一點。我已經編輯了這篇文章以包含更多的摘要。 – DeCaf 2013-04-23 17:48:32

2

使用ref時可能會有更多的性能問題,因爲在分配給變量時,這相當於額外的間接級別。但是,這種差異可能是微不足道的。

我寧願返回一個字符串的形式,這更說明了什麼是真正發生的事情,並允許您鏈方法調用在一起,如果你喜歡:

return AddFakeImage(ModifyLinks(HTML)); 

隨着ref形式你強制調用代碼來聲明一個變量,他們可能不需要。這妨礙了可讀性並增加了無意義的樣板代碼的發生率。

+0

從技術上講,在這兩種情況下都聲明瞭一個變量,這只是程序員是否需要知道的一個問題。在你給出的代碼示例中存在一個隱式的未命名局部變量。現在,這就是說,不必知道這件事是很好的,但從性能的角度來看,它沒有什麼不同。 – Servy 2013-04-23 17:43:58

+0

@Servy JIT編譯時會有一個寄存器,但是我已經顯示的代碼示例將聲明比原始代碼更少的本地代碼。縮寫的IL將是'ldarg.0;呼叫;呼叫; RET;'。所以不,沒有「附加變量」,至少在翻譯成本地代碼之前是沒有的。 (變量實際上並不存在於本地代碼中,只是寄存器和內存位置。變量的概念比本地代碼更高級。) – cdhowie 2013-04-23 17:46:00

+0

在這兩種情況下,無論是否存在命名本地,實際的處理器指令級別都很可能會被註冊,但如果不可能的話,兩者都可能被存儲在內存中的某個位置。 – Servy 2013-04-23 17:47:57

1

兩者之間的性能差異可以忽略不計。這幾乎完全是語法優先的問題。

標準約定將涉及返回一個新的字符串,而不是修改通過引用傳遞的參數。有幾種情況下使用起來更方便(即,當您沒有命名變量時;例如,當您想傳入方法或屬性的返回值而不是字段時)。

1

沒什麼區別,但我會用「迴歸」去。儘可能避免使用「ref」。

的原因是你不會有路過另一個調用的結果之前聲明一個變量,你可以調用鏈:

與裁判:

string modifyMe = GetMeString(); 
ModifyLints(ref modifyMe); 
AddFakeImage(ref modifyMe); 

相比返回:

string result = AddFakeImage(ModifyLinks(GetMeString())); 
1

如果您需要返回多個對象,請使用ref/out,如果您可以使用return執行此操作,只需返回一個obj等,使用return
ref使您的代碼不必要地模糊,併產生在這種情況下不必要的寫入開銷。
你應該總是儘量保持你的代碼簡單和可視化。

1

我喜歡的東西像一個製造商,其作用:。

新EmailMessageProcessor(HTML).WithModifiedLinks()WithFakeImages()。

所以沒有參考參數,一切都被封裝了。