我正在反对陈旧的返回代码与异常辩论,并且可以就具体示例提供一些建议。
我有一个简单的方法Authenticate,它采用典型的用户名,密码并在成功时返回会话密钥,否则返回失败原因。类似的东西:
Guid Authenticate(string username, string password)
虽然故障原因不会显示给用户,但我希望将这些故障原因传递给用户,以便他们采取适当的措施。
我认为有三组可能的回应:
1.成功
2.预期/常见故障,例如密码/用户无效,帐户已锁定
3.不寻常/意外的失败/例外,例如数据库连接失败等
通过返回有效的guid来指示1表示我很满意,并且通过异常冒充来表示我很满意,但是我应该为2做什么?
我正在走向异常,但我不确定一些常见的东西,比如错误的密码可能会在50%的情况下发生这种情况吗?替代方案是返回某种复杂的返回状态对象(如果成功则包括guid)或out参数?
答案 0 :(得分:4)
尝试使用模式Do()/TryDo()
以提高API的灵活性。因此,使用此API的客户端(类,服务等)将具有选项:
API:
// Throw in case of error with AuthenticateExceptionEventArgs
// contains information regarding error context
Guid Authenticate(string name, string password);
// Returns a status of operation, does not throw in case of error
AuthenticateStatus TryAuthenticate(string name, string password, out Guid guid);
需要以下基础架构类型:
enum AuthenticateStatus
{
Success,
InvalidPassword
}
class AuthenticateExceptionEventArgs : EventArgs
{
public AuthenticateStatus Status { get; private set; }
}
答案 1 :(得分:2)
您可以使用out
返回枚举,如果成功,则会设置Guid,否则您可以检查状态:
Guid Authenticate(string username, string password, out AuthResult authResult)
enum AuthResult {
Success,
BadPassword,
BadUserName,
....
}
或者,稍微转一下逻辑 - 从方法中返回一个枚举,并通过out
AuthResult Authenticate(string username, string password, out Guid guid)
答案 2 :(得分:1)
您知道可以使用不同类型的例外情况,具体取决于您计划如何处理它们。我建议将ApplicationException
用于您希望向用户显示的异常,并将Exception
用于您不希望显示的其他内容。
我强烈反对不支持联合类型的C#等语言中的特殊返回值。特殊返回值在Haskell等语言中正常工作,否则它们总是诉诸文档和错误来源的理由。
答案 3 :(得分:1)
异常的默认操作是程序死亡;返回代码的默认操作是程序继续。例如,如果该方法具有无效密码,如果它死亡或继续,会更好吗?这将是您确定是否应该使用异常或返回代码的标准。
答案 4 :(得分:0)
输出变量,就可以了,你可以使用Out变量Out Parameters
Guid Authenticate(string username, string password, out bool Status)
{
Status=false; //initially it will be false
if(LoginSuccess)
{
Status=True; // So that you can check whether the user is valid or not
}
}
用户这个函数调用就像这样
bool LoginStatus;
someGuidObj = Authenticate(username, password, out LoginStatus)
答案 5 :(得分:0)
返回自定义类型作为结果&不要抛出任何例外:
public class AuthenticationResult
{
// will be Guid.Empty if unable to authenticate.
public Guid SessionKey
{
get;
set;
}
public bool Authenticated
{
get
{
return this.SessionKey != Guid.Empty
}
}
// This will contain the login failure reason.
public string FailureMessage
{
get;
set;
}
}
如果需要,调用Authenticate方法的代码可以使用失败消息抛出异常。