重载的最佳实践

4

我有两个静态方法,用于错误处理。其中一个传递异常对象,另一个仅用于报告基于文本的消息(string errorMessage)的错误。

这两种方法中的代码几乎相同,除了如何构建消息并将其发送到日志文件。我该如何重构代码,以避免重复?

public static void ReportError(Exception exceptionRaised, string reference, string customMessage, bool sendEmail)
{
    // get filename
    // check if logfile exists, blah, blah
    // build up message from exception, reference & custom message using string builder
    // save message
    // email error (if set)
}

public static void ReportError(string errorMessage, string reference, bool sendEmail)
{
    // get filename
    // check if logfile exists, blah, blah
    // build up message from errorMessage & reference string builder
    // save message
    // email error (if set)
}

感谢。
6个回答

9

既然你在第一个方法中唯一不同的是构建自定义消息,那么请将自定义异常通过纯文本错误消息方法传递:

public static void ReportError(Exception exceptionRaised, string reference, 
    string customMessage, bool sendEmail)
{
    string errorMessage = BuildMessage(exceptionRaised, customMessage);
    ReportError(errorMessage, reference, sendEmail);
}

免责声明:不确定这是否有效。它取决于您如何构建错误消息。

编辑:

或者您可以添加第三个重载:

private static void ReportError(string completeException, bool sendEmail)
{
     // Do what needs to be done.
}

然后你的方法可以同时构建异常消息并将该字符串和sendEmail布尔值传递给第三个重载。


1
我个人更喜欢这个答案,因为它能够更清晰地展示这两种变体之间的关系。 - Simon D.
经过思考一分钟后,我认为这个解决方案比我的答案更好。(正如我所说,我的方法“肯定不是最优雅的方式,但它是一个起点”)。你不仅从我开始的同一点开始,而且走了更远的路。+1,并希望问题的提问者接受你的答案! - Treb

5

您是否可以只创建较少参数的重载函数,并将其调用具有更多参数的函数,传递null或""作为自定义消息?

public static void ReportError(string errorMessage,
                               string reference,
                               bool sendEmail)
{
    ReportError(errorMessage, reference, null, sendEmail);
}

请注意,如果你在使用C#4,你可以使用可选参数而无需重载函数。

3
一种简单的解决方法是将重复的代码提取到它自己的方法中,就像这样:

public static void ReportError(Exception exceptionRaised, string reference, string customMessage, bool sendEmail)
{
    // build up message from exception, reference & custom message using string builder
    ProcessError(Message, SendEmail)
}

public static void ReportError(string errorMessage, string reference, bool sendEmail)
{
    // build up message from errorMessage & reference string builder
    ProcessError(Message, SendEmail)
}

private static void ProcessError(string message, bool sendEmail)
{
    // get filename
    // check if logfile exists, blah, blah
    // save message
    // email error (if set)
}

这绝不是最优雅的方法,但这是个好的开始;-)

个人而言,我更喜欢这种工作方式,这也是我的答案。即使从开发用户的角度来看可以隐藏 ""null 值传递到方法中,我也不喜欢这样做。所以加1。 - djdd87
感谢您的回复。这似乎是我首选的方式,因为我也不喜欢发送null值。我注意到其他评论并重新排列了参数的顺序,并将字符串errorMessage重命名为字符串customMessage——与其他方法更加一致。非常感谢。 - StuffandBlah

1

在重载方法时,请确保第一个参数始终相同,否则会有点混淆。在您的情况下,将异常作为最后一个参数。

public static void ReportError(string customMessage, string reference, bool sendEmail, Exception exceptionRaised) 

关于代码重复。让两个方法都调用第三个受保护的方法,该方法执行实际处理。 异常方法可以在调用第三个方法之前格式化异常并将其添加到消息参数中。

保持参数对齐加1分。有时候我会忘记类接口是被人类(即阅读)而不是计算机所使用的。这是一个值得铭记的教训... - Treb

0
void report(Exception e)
{
  //convert exception to plain text
  string text = e.ToString();
  //re-use the other overload
  report(text);
}

void report(string text)
{
  ...etc...
}

一个更复杂的版本:
delegate string GetString();

public void report(Exception e)
{
  GetString getString = delegate() { return e.ToString(); }
  report(getText);
}

public void report(string text)
{
  GetString getString = delegate() { return text; }
  report(getText);
}

void report(GetString getString)
{
  ...etc...
  string text = getString();
  ...etc...
}

0
其他答案都不错,但是我想补充一些我遇到过的维护上的麻烦。
public void report(string text)
{
   ...
   report(text,defaultvalue);
}

public void report(string text, string email)
{
   ...
   report(text,email,null);
}

public void report(string text, string email, List<string> errors)
{
   ...
}
...
etc.

当你不得不重构所有这些方法只是因为你想改变其中一个方法的参数时,这往往会非常令人烦恼。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接