2013-08-26 109 views
6

雖然我在C#中處理一些較舊的代碼,但遇到了令我厭煩的代碼。返回賦值表達式

不無事生非,它是這樣的:

private string foo(string _text) 
{ 
    /* some manipulation on _text */ 
    return _text = Server.HtmlDecode(_text); 
} 

這是它惹惱了我的最後一行;我來自C背景,我可以理解代碼實際上試圖返回一個解碼的_text變量。另外賦值運算符的值是左操作數,所以我可以看到它。

但我仍然覺得很討厭。

是否需要習慣於C#中的縱座標操作?

對我來說,最後一行應該簡單地

return Server.HtmlDecode(_text); 

並沒有賦值表達式。有沒有更深的C#功能,我不知道?

+0

'_text'絕對不是全局變量,它是方法的參數。 –

+0

這項任務實際上是否有必要?之後您將無法使用'_text'做任何事情,而且很可能會超出範圍。 –

+0

@lc。這正是我所部分要求的;如果它有任何意義。根據我收集的內容,我想不是。 –

回答

10

當我工作的一些在C#中的老代碼,我遇到這激怒了我一個代碼。

這裏有許多令人討厭的問題。讓我們把它們全部列出來。

private string foo(string _text) 
{ 
    /* some manipulation on _text */ 
    return _text = Server.HtmlDecode(_text); 
} 

這是這惹惱我

註釋也令人側目的最後一行。局部變量是便宜。沒有必要清除_text的原始值。相反,創建一個新的局部變量並對其進行操作。這樣,當您在該方法的任何時候調試時,您可以知道原始參數是。 (記住,原始的參數可能有資格進行垃圾回收的時刻變量被覆蓋,因此可能會永遠消失。)

不要寫了一個正式的參數沒有一個很好的理由。這使它更難調試。

賦值運算符的值是左操作數,所以我可以看到它。

在這種情況下,這是正確的,但總的來說是微妙的錯誤;在C#賦值運算符的值是操作數被轉換到與左手側關聯的類型後的值。請記住,左手邊可能沒有價值;它可能是一個只寫屬性。

在C#中,我需要習慣嗎?

這裏有一個標準的做法,是的。什麼是奇異的有關此用法是(1),所選擇的變量是一個正規的,和(2)的分配與return組合。

這將是C#標準的做法,說:

string decoded = Server.HtmlDecode(_text); 
return decoded; 

現在你可能不知道的這個誘人的好處是對你有什麼建議:

return Server.HtmlDecode(_text); 

答案是:前Visual Studio 2013中,調試器中沒有設施來檢查方法調用的返回值!因此,如果你想看看通過HtmlDecode返回的值是在調試時你有以下選擇:在組件級別

  • 調試,並期待在EAX的內容
  • 步入HtmlDecode並檢查其狀態
  • 步驟出來的當前方法和檢驗任何返回值被分配到
  • 結果分配到另外無用局部變量然後檢查本地在調試器

由於前三個是可怕的,而最後一個很容易,所以許多C#程序員都習慣於這樣做。

如果你這樣做,然後做使用生成的地方,C#編譯器知道,這是一種常見的做法,故意抑制「你寫信給你,然後從不讀當地的」警告。如果本地有一個常量寫入它,它只會給出警告,在這種情況下,您已經知道它在編譯時是什麼,通常不需要在調試器中檢查它。

希望現在VS2013終於支持這個經常要求的功能,這種模式會逐漸消失。

+0

,你會介意擴大這個評論嗎? 「請記住,在變量被覆蓋的時候,原始參數可能有資格進行垃圾回收,因此可能會永遠丟失」 –

+0

@Jace Kim:如果變量被覆蓋,則可能是參數沒有實時引用, GC可以收集它。 – InBetween

0

不,這是一件愚蠢的事情,它犧牲了可讀性,將更多代碼塞進一行。這幾乎總是一件壞事。

在這種情況下,它實際上沒有任何用途。 _text是方法的參數,並且在方法體中更改它不會完成任何操作。傳遞給該方法的字符串將不會被修改。

0

它們具有相同的結果。這是最常見的,看後者,或:

_text = Server.HtmlDecode(_text); 
return _text; 

(我喜歡上述任一或return Server.HtmlDecode(_text);,但它是不是你正在閱讀的代碼的方式)

+0

我更喜歡'Server.HtmlDecode(_text);'。這就是說,我更喜歡使用本地聲明的字符串來存儲字符串操作。 –

+0

好的。我只是想知道是否有一些我不知道的或者我找不到的C#特性。來自C和Lisp的C#似乎有很多黑魔法師在背後。 –

0

沒有,有沒有更深層次的C#特性在這種情況下,做return聲明中的任務是毫無意義的。它只會使得難以遵循代碼應該做的事情。

與您建議的唯一區別在於解碼值被分配給_text變量,但由於該變量不再被使用,因此該方法結束時的值是多少並不重要。該參數是方法內部的一個局部變量,不會影響方法外的任何內容。

+0

如果return語句返回_text的值,或者'賦值表達式的結果',則後續問題將會出現。這是一個很迂腐的問題。 C#程序員是否使用「值賦值表達式」?我已經避免了它在C中的可讀性,但是我已經看到足夠的代碼來使它厭倦它。 –

+0

@JaceKim:'return'語句返回表達式的值,賦值表達式的值是分配的值。該值不會再從變量中讀取以返回。 C#程序員有時使用賦值作爲表達式,但不是很頻繁。當替代方案是一個更復雜的控制結構時,主要使用它,例如,當值確定循環應該繼續時; while((line = stream.ReadLine())!= null)...' – Guffa

+0

非常感謝你;它很明顯。如果可以, –

2

這個聲明是多餘的,並且不是一個C#的做法。

這樣做,而ReSharper的活躍也將給予警告

指派任何執行路徑沒有使用的價值

至於你提到的這個代碼確實是最好的做法

return Server.HtmlDecode(_text); 

此外,由於解碼是_text上的操作的一部分,因此分離賦值和返回狀態也是有效的NT,保持邏輯在同一個塊:

/* Other manipulations on _text */ 
_text = Server.HtmlDecode(_text); 

return _text;