我在C#工作,所以我在C#下发布了这个,尽管这可能是一个可以用任何编程语言回答的问题。
有时我会创建一种方法来执行诸如将用户登录到网站之类的操作。通常我会从方法返回一个布尔值,但这通常会导致问题,因为布尔返回值不会传达任何上下文。如果在登录用户时发生错误,我无法知道导致错误的原因。
以下是我当前使用的方法示例,但希望更改以便返回的结果不仅仅是0或1。
public bool LoginToTwitter(String username, String password)
{
// Some code to log the user in
}
上述方法只能返回True或False。这很有效,因为我可以调用以下内容:
if(http.LoginToTwitter(username, password))
{
// Logged in
} else {
// Not Logged in
}
但问题是我无法知道用户为什么没有登录。可能存在多种原因,例如:错误的用户名/密码组合,暂停帐户,帐户需要用户注意等等。但使用以下内容方法和逻辑,不可能知道这一点。
我有哪些替代方法?
答案 0 :(得分:8)
您可以使用预期的LoginResults创建并返回enum
。
public enum LoginResult
{
Success,
AccountSuspended,
WrongUsername,
WrongPassword,
}
然后使用方法中的枚举类型返回:
public LoginResult LoginToTwitter(String username, String password)
{
// Some code to log the user in
}
答案 1 :(得分:8)
您可以选择抛出附加了相关消息的异常(并使调用方法处理异常),或让函数返回具有不同状态的enum
(例如LoginState.Success
,LoginState.IncorrectPassword
等。)。
如果您正在使用异常,最好让您的函数不返回任何内容(public void LoginToTwitter
),但如果您使用enum
,请确保将返回类型设置为名称您的enum
(public LoginState LoginToTwitter
)。
答案 2 :(得分:6)
有两种标准方式。如果您只对结果感兴趣,而不是对任何元数据感兴趣,请返回一些枚举。将可用值设置为Success
,Suspended
等(所有可能的结果)
如果您需要更多详细信息,可以随时使用例外。基本上遵循“告诉,不要问”的想法并以一种方式编写你的函数,它只返回成功时返回所需的值(例如用户id?或者如果你有一些全局登录状态则没有任何内容)并抛出一个详细的异常否则说明失败。关于层次结构本身,您最有可能实现具有更多特定子类的LoginException
并仅捕获那些子类。 (它可以很容易地验证所有相关的异常都得到处理,所有未知的异常都被传递到更高的级别)
答案 3 :(得分:3)
如其他答案所示,返回枚举或抛出异常都是合理的。但我的偏好是返回异常。听起来很疯狂,但它让调用者决定是使用错误检查还是异常处理。并且,与enum不同,异常是分层的,因此它可以更容易地处理整个类别的故障,并且可以携带任意额外的数据。
我认为Sayse有类似的想法,但他删除了他的答案,从未真正解释过。
答案 4 :(得分:0)
根据干净的代码倾向,您应该为您的方法提供一个有意义的名称,以揭示意图。
要知道如果日志操作无法完成会发生什么,您可以在流Exceptions
中引入并在调用者上下文中处理它。
请参阅http://msdn.microsoft.com/en-us/library/ms173160(v=vs.80).aspx
答案 5 :(得分: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
“简单赋值表达式的结果是赋给左操作数的值。结果与左操作数的类型相同,并且始终归类为值。”