我正在使用具有以下签名的方法:
public static bool TryAuthenticate(string userName, string password,
string domainName, out AuthenticationFailure authenticationFailure)
该方法声明:bool authenticated = false;
然后继续验证用户。
每当authenticated
设置为true或false时,authenticationFailure
都会相应地设置为AuthenticationFailure.Failure
或AuthenticationFailure.Success
。
所以基本上我可以使用authenticationFailure或方法的返回值来检查结果。然而,在同一方法中使用这两种方法似乎是对DRY的毫无意义的违反。
为了澄清一下,在方法的其他任何地方都没有使用authenticationFailure,因此它看起来完全是多余的。
目前我正在这样做:
public static bool IsValidLDAPUser(string username, string password, string domain)
{
var authenticationStatus = new AuthenticationFailure();
if (ActiveDirectoryAuthenticationService.TryAuthenticate(username, password, domain, out authenticationStatus))
return true;
else return false;
}
但我可以这样做并获得类似的结果:
public static AuthenticationFailure IsValidLDAPUser(string username, string password, string domain)
{
var authenticationStatus = new AuthenticationFailure();
ActiveDirectoryAuthenticationService.TryAuthenticate(username, password, domain, out authenticationStatus)
return authenticationStatus;
}
提前致谢!
答案 0 :(得分:4)
通常错误代码多于成功或失败。也许这种方法的设计者会为所有不同的故障类型添加更多的枚举。
有时,还有不止一种成功类型 - 例如HTTP在200和300块中有很多返回代码,这些代码在某种程度上都被认为是成功的。所以bool一般会告诉你它是否成功,并且枚举提供了更准确的信息。
有很多方法可以做到,而且这个方法很不寻常,但如果他们计划添加更多代码,则不会反对DRY。
另一种方法是封装到具有枚举和Result
属性的IsSuccess
类中。您甚至可以提供bool转换,以便在if语句中使用。
答案 1 :(得分:3)
首先,你的枚举变量名称似乎有点扭曲。 AuthenticationFailure.Success
没有多大意义!它应该是AuthenticationResult
或其他东西。此外,因为在您的方法中,您只关心身份验证是否成功,您应该返回bool。你在考虑干,但也想到KISS!
您仍然可以将枚举用于您可能添加的其他错误代码,但是查看方法的返回值应该告诉您它是否成功。如果您想查找原因不成功的详细信息,请使用作为'out'参数传递的枚举。
答案 2 :(得分:2)
如果函数只返回一个值,则应优先使用常规函数返回值,而不是out
或ref
参数。
我想说这对于名为IsXyz的方法更重要(重点在于是),以这种方式命名的方法应该返回bool
。
答案 3 :(得分:1)
与返回值相比,参数参数不易于使用和理解。但是,有一些情况下使用ref参数可能是有利的。对于这种情况,如果我们假设分配AuthenticationFailure非常耗时,那么使用ref参数是合适的,因为在身份验证成功的情况下不需要分配。
无论如何,在这种情况下,我更喜欢使用AuthenticationResult返回类型,因为不应该对性能产生影响。
答案 4 :(得分:1)
我希望看到以下方法
public static bool TryAuthenticate(string userName,
string password,
string domainName,
out User user)
和
public static User Authenticate(string userName,
string password,
string domainName)
当你不关心为什么和你做的时候。 e.g。
这允许调用代码进行身份验证,然后执行没有catch的操作
User u;
if (TryAuthenticate(user,pass,domain,ref u))
//do somthing
else
return;
或者,如果他们需要额外的信息,那么使用catch
e.g。
User u;
try
{
u = Authenticate(user,pass,domain);
//do somthing
}
catch(AuthenticationError ae)
{
switch (ae.Failure)
{
case AuthenticationFailure.AccountLocked:
//dosomthing A
break;
case AuthenticationFailure.BadPassword:
//dosomthing B
break;
case AuthenticationFailure.InvalidUser:
//dosomthing c
break;
etc..
}
}
现在,如果没有用户或令牌的概念,则可能不需要尝试模式