检查参考参数值或返回bool?

时间:2010-09-01 15:27:55

标签: c# .net methods pass-by-reference

我正在使用具有以下签名的方法:

public static bool TryAuthenticate(string userName, string password, 
    string domainName, out AuthenticationFailure authenticationFailure)

该方法声明:bool authenticated = false;然后继续验证用户。

每当authenticated设置为true或false时,authenticationFailure都会相应地设置为AuthenticationFailure.FailureAuthenticationFailure.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;
}
  • 为什么你的参考参数与返回值的作用相同?
  • 我应该使用哪一个来检查结果,是否有任何区别?
  • 这只是一个坏代码的情况还是我错过了这一点?

提前致谢!

5 个答案:

答案 0 :(得分:4)

通常错误代码多于成功或失败。也许这种方法的设计者会为所有不同的故障类型添加更多的枚举。

有时,还有不止一种成功类型 - 例如HTTP在200和300块中有很多返回代码,这些代码在某种程度上都被认为是成功的。所以bool一般会告诉你它是否成功,并且枚举提供了更准确的信息。

有很多方法可以做到,而且这个方法很不寻常,但如果他们计划添加更多代码,则不会反对DRY。

另一种方法是封装到具有枚举和Result属性的IsSuccess类中。您甚至可以提供bool转换,以便在if语句中使用。

答案 1 :(得分:3)

首先,你的枚举变量名称似乎有点扭曲。 AuthenticationFailure.Success没有多大意义!它应该是AuthenticationResult或其他东西。此外,因为在您的方法中,您只关心身份验证是否成功,您应该返回bool。你在考虑干,但也想到KISS!

您仍然可以将枚举用于您可能添加的其他错误代码,但是查看方法的返回值应该告诉您它是否成功。如果您想查找原因不成功的详细信息,请使用作为'out'参数传递的枚举。

答案 2 :(得分:2)

如果函数只返回一个值,则应优先使用常规函数返回值,而不是outref参数。

我想说这对于名为IsXyz的方法更重要(重点在于),以这种方式命名的方法应该返回bool

答案 3 :(得分:1)

与返回值相比,参数参数不易于使用和理解。但是,有一些情况下使用ref参数可能是有利的。对于这种情况,如果我们假设分配AuthenticationFailure非常耗时,那么使用ref参数是合适的,因为在身份验证成功的情况下不需要分配。

无论如何,在这种情况下,我更喜欢使用AuthenticationResult返回类型,因为不应该对性能产生影响。

答案 4 :(得分: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)

当你不关心为什么和你做的时候。 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..

    }
}

现在,如果没有用户或令牌的概念,则可能不需要尝试模式