Exception 还什么?错误字符串、带错误字符串的Bool或带异常的Void

Exception 还什么?错误字符串、带错误字符串的Bool或带异常的Void,exception,exception-handling,return-value,return,Exception,Exception Handling,Return Value,Return,我把大部分时间花在C#上,试图找出处理异常的最佳实践,并将错误消息从被调用方法干净地返回给调用方法 例如,下面是一些ActiveDirectory身份验证代码请将此方法想象为类的一部分(而不仅仅是一个独立函数) 这样做的好处是,可以在If-Then-Else语句中明确表示是或否。缺点是,它还要求使用该方法的人提供一个字符串以返回错误(如果有) 我想我可以用相同的参数减去“out errStr”来重载这个方法,但是忽略这个错误似乎是个坏主意,因为这样的失败可能有很多原因 或者,我可以编写一个返回错

我把大部分时间花在C#上,试图找出处理异常的最佳实践,并将错误消息从被调用方法干净地返回给调用方法

例如,下面是一些ActiveDirectory身份验证代码请将此方法想象为类的一部分(而不仅仅是一个独立函数)

这样做的好处是,可以在If-Then-Else语句中明确表示是或否。缺点是,它还要求使用该方法的人提供一个字符串以返回错误(如果有)

我想我可以用相同的参数减去“out errStr”来重载这个方法,但是忽略这个错误似乎是个坏主意,因为这样的失败可能有很多原因

或者,我可以编写一个返回错误字符串的方法(而不是使用“out errStr”),其中返回的空字符串表示用户可以通过身份验证

string AuthenticateUser(string domain, string user, string pass)
{
  string errStr = "";
  try
  {
    // Instantiate Directory Entry object
    DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);

    // Force connection over network to authenticate
    object nativeObject = entry.NativeObject;
  }
  catch (Exception e) { errStr = e.Message().ToString(); }
  return errStr;
}
但这似乎是一种“软弱”的做事方式

或者我应该将我的方法设置为“void”,而不处理异常,以便将其传递回调用函数吗

void AuthenticateUser(string domain, string user, string pass)
{ 
   // Instantiate Directory Entry object
   DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);

   // Force connection over network to authenticate
   object nativeObject = entry.NativeObject; 
}
这对我来说似乎是最理智的(出于某种原因)。但同时,与只在需要验证的地方键入这两行相比,包装这两行的唯一真正优势在于,我不需要包含“LDAP://”字符串。这种方法的缺点是,用户必须将此方法放入try-catch块中

想法


有没有其他我没有想到的方法呢?

不要处理异常或返回任何类型的消息。让你的方法的消费者来处理这个问题。

没有“一刀切”的办法。如果您返回一个标志,则可以方便地在
If()
和循环中使用方法。异常总是需要大量的锅炉板代码。如果您只需要一个可以向用户显示的字符串(比如,在web UI中),那么返回错误字符串(或者为“无错误”返回
null
)也很好

但大多数时候,我抛出一个异常(在Java中是
RuntimeException
的子类),因为这允许我返回有关错误的多个信息(例如:哪个文件导致了错误?哪个行/列?我在做什么?表单中的哪个字段应该标记为非法?等等)


在您的情况下,您无法在方法中处理异常,因此不应该捕获它。只有当你能做点什么的时候才能抓住它。

在这个例子中,我同意,你应该让异常流通过消费者。但是,作为您强调的方法的另一种选择,请考虑这种方法。

您可以使用响应对象保存方法运行产生的信息,例如:

public abstract class BaseResponse
{
  public bool IsOk { get; protected set;}
  public string Message { get; protected set; }
}

public class AuthenticationResponse: BaseResponse
{
  public AuthenticationResponse(bool isOk): this(isOk, "") {}
  public AuthenticationResponse(bool isOk, string message)
  {
    IsOk = isOk;
    Message = message;
  }
}

AuthenticationResponse IsUserAuthenticated(string domain, string user, string pass)
{
  bool authentic = false;
  string errStr;
  try
  {
    // Instantiate Directory Entry object
    DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, user, pass);

    // Force connection over network to authenticate
    object nativeObject = entry.NativeObject;

    // No exception thrown? We must be good, then.
    authentic = true;
  }
  catch (Exception e) { errStr = e.Message().ToString(); }
  return new AuthenticationResponse(authentic, errStr);
}
然后在if语句中使用它:

AuthenticationResponse response;
if((response = IsUserAuthenticated("domain", "user", "pass")).IsOk)
{
  // do successful activity
} else {
  Console.WriteLine(response.Message)
}
诀窍在于赋值操作的返回值就是被赋值的值。因此,我们可以在同一行中进行赋值和有效检查。如果不需要保留调用的结果,只需调用该方法并检查IsOk属性即可

if(IsUserAuthenticated("domain", "user", "pass").IsOk)
{
  // do successful activity
}
然后,您可以构建自定义响应对象,根据需要从方法返回任意值组合。

+1--哇!那太聪明了!即使我对你所做的感到惊讶,我也不确定我是否会在实践中实现它。也许我只能让它在我的脑子里酝酿一段时间,也许我会适应它…:-)谢谢
if(IsUserAuthenticated("domain", "user", "pass").IsOk)
{
  // do successful activity
}