2013-07-21 58 views
8

我在C#中工作,所以我已經在C#下發布了這個,儘管這可能是一個可以用任何編程語言回答的問題。返回有意義的返回值的方法

有時我會創建一個方法來做一些事情,例如將用戶登錄到網站。通常情況下,我從方法返回一個布爾值,但是這經常會導致問題,因爲布爾返回值沒有傳達任何上下文。如果在登錄用戶時發生錯誤,我無法知道導致錯誤的原因。

這裏是我目前使用的方法的例子,但想改變,因此它返回的不僅僅是0或1

public bool LoginToTwitter(String username, String password) 
{ 
    // Some code to log the user in 
} 

上述方法更只能返回真或假。這個效果很好,因爲我可以調用如下。

if(http.LoginToTwitter(username, password)) 
{ 
    // Logged in 
} else { 
    // Not Logged in 
} 

但問題是我不知道爲什麼在沒有登錄用戶的方式有很多原因可能存在,如:錯誤的用戶名/密碼組合,暫停帳戶,帳戶需要用戶注意等。但使用以下方法和邏輯,不可能知道這一點。

我有什麼替代方法?

回答

8

您可以使用預期的LoginResults創建並返回enum

public enum LoginResult 
{ 
    Success, 
    AccountSuspended, 
    WrongUsername, 
    WrongPassword, 
} 

然後返回你的方法用枚舉類型:

public LoginResult LoginToTwitter(String username, String password) 
{ 
    // Some code to log the user in 
} 
+0

發生新的錯誤情況時發生了什麼。 @丹? – xhamr

+0

@jvra如果有任何意外的例外,我相信他們應該重新拋出,因爲一些其他的答案表明。但是,您的代碼應該能夠處理所有預期的情況:錯誤的用戶名,錯誤的密碼,帳戶暫停等等,並將這些預期情況返回給您的應用程序處理的枚舉。 –

+0

但事實是,當你想處理其他錯誤枚舉。你的代碼會隨着你的常量枚舉的增長而增長。但如果你知道將來你不可能有更多的常量枚舉,那麼這是可以接受的。 – xhamr

8

你可以選擇是拋出附有相關信息的異常(並有調用的方法處理除外),或該函數返回具有不同狀態的enum(如LoginState.SuccessLoginState.IncorrectPassword等)。

如果您使用的例外,它可能是最好的讓你的函數返回什麼(public void LoginToTwitter),但如果您使用的是enum,確保設定的返回類型的名稱,您enumpublic LoginState LoginToTwitter)。

6

有兩種標準方式。如果您只對結果感興趣,但不感興趣,請返回一些枚舉。將可用值設置爲Success,Suspended等(所有可能的結果)

如果您需要更多詳細信息,則可以始終使用例外情況。基本上按照「告訴,不要問」的想法,並寫一個你的函數的方式,它返回所需的值(例如用戶ID?或者可能沒有,如果你有一些全局登錄狀態)只有在成功和拋出一個異常詳細否則描述失敗。關於層次結構本身,你應該最有可能實現一個LoginException與一些更具體的子類,並只捕獲那些。 (它可以很容易地驗證所有相關的異常處理,並將所有未知的異常處理到更高級別)

3

兩個返回一個枚舉或拋出一個異常,在其他的答案建議,是合理的。但我的首選是返回異常。聽起來很瘋狂,但它可以讓你的調用者決定是否使用錯誤檢查或異常處理。而且,與枚舉不同的是,異常是分層的,因此處理整個類別的失敗變得更加容易,並且可以攜帶任意額外的數據。

我覺得Sayse有一個類似的想法,但他刪除了他的答案,從來沒有真正解釋過它。

+0

所以基本上,'null'就意味着*成功* - 這看起來相當違反直覺。當然,如果你真的需要一個返回值,比如(說)用戶信息......我可以用Smalltalk這種動態類型的語言看到它的一個很好的例子,但是像C#這樣的靜態類型語言使得這種麻煩。 – cHao

+0

@cHao:如果進一步處理需要返回一些其他信息,則拋出異常開始變得更有意義。但是,如果登錄失敗是預期的結果......以及我不會在非特殊情況下使用「throw」。 –

+0

我半驚訝沒有人認爲是一個'LoginResult'類型,它不是一個例外,但也不僅僅是一個枚舉。它會提供返回任意信息的靈活性,而不會誘使人們拋出非例外條件的例外情況。 – cHao

0

您可以使用c中經常使用的習語。賦值表達式的結果是表達式本身 - 這意味着你可以在同一時間捕捉的結果代碼爲評估它是否是一個特定的值:

if ((status = DoSomething()) == AnErrorEnum.NotAnError) 
{//success handler 
} 
else 
{//failure handler 
} 

我被要求提供一個鏈接到一個MSDN文章 - 這裏是舊版本的規範: http://msdn.microsoft.com/en-us/library/aa691315(v=vs.71).aspx

「簡單賦值表達式的結果是分配給左操作數的值,結果與左操作數的類型相同,並且始終歸類爲值。 「

+0

這很有趣。請鏈接到MSDN文檔? –

+0

這是在規格,它是可供下載:這是2003年舊規格的部分:http://msdn.microsoft.com/en-us/library/aa691315(v=vs.71).aspx –