检查参考参数值还是返回布尔值?
Posted
技术标签:
【中文标题】检查参考参数值还是返回布尔值?【英文标题】:Check reference parameter value or return bool? 【发布时间】:2011-04-06 21:20:32 【问题描述】:我正在使用具有以下签名的方法:
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;
为什么会有一个与返回值做同样事情的引用参数?
我应该使用哪一个来检查结果,它有什么不同吗?
这只是代码错误还是我没有抓住重点?
提前致谢!
【问题讨论】:
我认为您的第二个代码块可能包含错误。返回类型不应该是bool
而不是AuthenticationFailure
还是应该将return 语句更改为返回authenticationStatus
?
【参考方案1】:
恕我直言,我不认为这是 bool vs ref 的事情。对我来说,似乎在参考中返回了错误的东西。
我希望看到以下方法
public static bool TryAuthenticate(string userName,
string password,
string domainName,
out User user)
和
public static User Authenticate(string userName,
string password,
string domainName)
一种用于您不关心原因的情况,另一种用于您关心的情况。例如
这允许调用代码进行身份验证,然后在没有捕获的情况下执行某些操作
User u;
if (TryAuthenticate(user,pass,domain,ref u))
//do somthing
else
return;
或者,如果他们需要额外的信息,那么使用 catch
例如
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..
现在如果没有用户或令牌的概念,那么可能不需要 Try Pattern
【讨论】:
【参考方案2】:与返回值相比,Ref 参数不太容易使用和理解。但是,在某些情况下,使用 ref 参数可能是有利的。对于这种情况,如果我们假设分配 AuthenticationFailure 是耗时的,那么使用 ref 参数是合适的,因为在认证成功的情况下不需要分配。
无论如何,在这种情况下,我更喜欢使用 AuthenticationResult 返回类型,因为应该不会影响性能。
【讨论】:
【参考方案3】:首先,您的枚举变量名称对我来说似乎有点扭曲。 AuthenticationFailure.Success
没有多大意义!应该是AuthenticationResult
之类的。此外,由于在您的方法中您只关心身份验证是否成功,因此您应该返回 bool。你在想 DRY 但也想 KISS!
您仍然可以将枚举用于您可能添加的其他错误代码,但是查看方法的返回值应该会告诉您它是否成功。如果您希望找到失败原因的详细信息,请使用作为“out”参数传递的枚举。
【讨论】:
是的,我注意到枚举的命名并没有经过深思熟虑。幸运的是,这段代码不是我编写的,我也不维护它——它是公司范围内巨大的通用库之一。【参考方案4】:通常有更多的错误代码,而不仅仅是成功或失败。也许这种方法的设计者会为所有不同的故障类型添加更多的枚举。
有时,也有不止一种成功类型——例如。 HTTP 在 200 和 300 块中有很多返回码,它们在某种程度上都被认为是成功的。因此,布尔值通常会告诉您它是否成功,而枚举会提供更准确的信息。
有很多方法可以做到这一点,这一种是不寻常的,但如果他们计划添加更多代码,则不反对 DRY。
另一种方法是封装到具有枚举和IsSuccess
属性的Result
类中。您甚至可以提供到 bool 的转换,以便在 if 语句中使用。
【讨论】:
好点 - 我刚刚看了一下 TryAuthenticate 的可扩展性,结果发现 AuthenticationFailure 有各种其他值,如 AccountDisabled、PasswordExpired、InvalidWorkstation 等等......所以我将继续检查布尔值,但当身份验证失败时可能会使用 AuthenticationFailure 来提供一些关于失败原因的反馈。【参考方案5】:如果函数只返回一个值,则应优先使用常规函数返回值,而不是 out
或 ref
参数。
我想说这对于名为 IsXyz 的方法(重点是 is)更为重要,并且以这种方式命名的方法应该返回 bool
。
【讨论】:
以上是关于检查参考参数值还是返回布尔值?的主要内容,如果未能解决你的问题,请参考以下文章