В случае успеха, я хочу вернуть строку AccessToken, если нет, я хочу вернуть сообщение об ошибке. Это обе строки, поэтому проблем нет. Но когда вы проверяете возвращаемое значение на вызывающей стороне кода, как вы можете это сделать эффективно?
C# на самом деле не использует сообщения об ошибках, мы используем exceptions. Правильный способ сделать это - просто выбросить исключение и позволить вызывающему абоненту игнорировать или улавливать его.
Если это не «исключительный» сбой (например, если у некоторых пользователей есть токены, а у некоторых нет), то альтернативой было бы вернуть пустую строку, указывающую на отсутствие токена (и все еще бросать исключение для «исключительных» случаев, таких как невозможность связаться с Facebook и т. д.). Я не думаю, что это так, потому что ваш пример неудачи включал объект Exception.
Подводящий итог, заключается в том, что вы обычно оставляете обработку исключений (catch) до самой верхней части стека (обычно, пользовательский интерфейс), поскольку это имеет самый контекст текущей операции. Не имеет смысла ловить исключение, переформатировать строку и затем вернуть это вместо этого - потерять важную информацию об исключении на этом пути. Просто позвольте вызывающему абоненту иметь исключение вместо этого, и они могут решить, как представить эту ошибку пользователю (или продолжить без интеграции FB).
Это, очевидно, издевались, но, надеюсь, получает мой пункт через (код говорит громче, чем слова):
class Facebook {
...
public string GetAccessToken(string username, string password) {
// can throw WebException if can't connect to FB
this.Connect();
// returns null token if not a Facebook user
if (!this.IsUser(username)) return null;
// can throw ArgumentException if password is wrong
var fbInfo = this.GetInfo(username, password);
return fbInfo.AccessToken;
}
...
}
class Page {
void Page_Load(object sender, EventArgs e) {
var fb = new Facebook();
string accessToken;
try {
accessToken = fb.GetAccessToken(this.User.Name, this.txtPassword.Text);
} catch (WebException ex) {
Log(ex);
this.divError.Text = "Sorry, Facebook is down";
// continue processing without Facebook
} catch (ArgumentException ex) {
// Don't log - we don't care
this.divError.Text = "Your password is invalid";
// stop processing, let the user correct password
return;
} catch (Exception ex) {
Log(ex);
// Unknown error. Stop processing and show friendly message
throw;
}
if (!string.IsNullOrEmpty(accessToken)) {
// enable Facebook integration
this.FillFacebookWallPosts(accessToken);
} else {
// disable Facebook integration
this.HideFacebook();
}
}
}
Может также сделать его общим по любому типу результата, а не ju st 'AccessToken' – Alexander