22

我有一些执行日志记录的 C# 应用程序,并且 Output 方法具有接受消息和 StreamWriter 的重载,以及带有 params 数组的附加参数的另一个重载。方法签名的一个示例是:

private static void Output(string message, StreamWriter writer, params object[] args) 
{..}

private static void Output(string message, StreamWriter writer) 
{..}

问题涉及 Resharper,它为这些方法提供以下警告:“带有可选参数的方法被重载隐藏”。

该警告具有误导性,因为我从 3 参数重载内部调用 2 参数重载并且它不会导致递归调用,因此不会隐藏重载。

我在 Resharper 网站上进行了一些研究,在这个问题上已经打开了一些票,这些票已被关闭为“无法修复”。

在我看来,这是一个有效的用例,因为运行时知道要调用哪个重载。.NET 框架中也有使用此类重载的示例。

例如,StreamWriter.WriteLine()具有要写入的值的重载,还有Format params.

这是一个有效的参数,还是应该将我的方法重命名为“OutputFormat”之类的东西,因为他们在幕后使用 string.Format 来构建具有指定参数的字符串?

4

1 回答 1

29

据我所知,您的帖子中有两个问题。

首先,如果你觉得你的方法可以重命名为更明显的东西,那将在许多方面(可读性、可用性等)改进你的代码,并且无论如何它们应该尽可能地描述它们所做的事情。

、关于 Resharper 警告:

使用重载函数的递归并不一定意味着或导致您看到的警告。

您可能知道重载函数最常用于当函数的参数具有不同类型时,但函数执行相同的操作,例如:

private static void Print(int i) {...}

private static void Print(bool b) {...}

但是,如果一个函数被重载并且该重载具有完全相同的参数类型以及可选参数,那么您很可能遇到了设计问题。

基本解释

如果你有这样的事情:

private static void Print(string message) {...}

private static void Print(string message, string messageDelimiter = "===\n") {...}

当你从你的类中调用 Print 函数时,因为当你调用它们时这两个函数看起来都是一样的:Print("my message");带有可选参数的那个是隐藏的。

因此,您可以像这样简单地合并它们:

private static void Print(string message, string messageDelimiter = "===\n") {...}

而且

您可能还想做一些更聪明的事情,比如让用户访问一个公共功能,同时使用可选参数限制一个:

public static void Print(string message) {...} //< As you can see this one is public

private static void Print(string message, string messageDelimiter = "===\n") {...}

即使那样的话,你也会遇到同样的问题。

IMO,一个好的经验法则是问自己几个问题:

  • 可选参数在哪里真的有意义吗?
  • 函数真的需要保持相同的名称吗?
  • 参数真的应该是可选的吗?

如果您对所有这些回答都是肯定的,那么忽略 Resharper 评论并让您的代码保持原样可能是“可以的”。

于 2013-06-05T05:05:36.403 回答