C# 我们应该总是显式地指定ToString()吗?

C# 我们应该总是显式地指定ToString()吗?,c#,object-oriented-analysis,C#,Object Oriented Analysis,我有一个自定义类结构,如下所示 public interface Stuff { } public Thing : Stuff { public new String ToString() { return "That's the thing!"; } } 然后,在我的代码的其他部分中,我有一个将字符串对象作为参数的方法。第一行编译,而第二行不编译。我认为在发送对象时默认调用ToString。从对象类继承的东西应该已经实现了ToString(在我的例子中,也被my实现所掩盖) 我错过

我有一个自定义类结构,如下所示

public interface Stuff { }
public Thing : Stuff 
{ 
  public new String ToString() { return "That's the thing!"; } 
}
然后,在我的代码的其他部分中,我有一个将字符串对象作为参数的方法。第一行编译,而第二行不编译。我认为在发送对象时默认调用ToString。从对象类继承的东西应该已经实现了ToString(在我的例子中,也被my实现所掩盖)


我错过了什么?

您可能会因为调用
String.Format
Console.WriteLine
以及字符串连接操作符而感到困惑,这些操作符简单地调用
字符串

但这并不是一般的规则。通常,如果需要字符串,则需要显式调用
ToString
,或者进行其他转换。我不建议创建到
string
的隐式转换-它们可能会带来更多的痛苦而不是快乐


我还建议不要创建新的
ToString
方法。相反,您应该覆盖由
对象
声明的对象。隐藏方法几乎总是一个坏主意;在某些情况下,您确实希望这样做(例如更改返回类型),但应尽可能避免这样做。

您可能会因为调用
String.Format
Console.WriteLine
,以及字符串串联运算符而感到困惑,这些运算符简单地调用
字符串

但这并不是一般的规则。通常,如果需要字符串,则需要显式调用
ToString
,或者进行其他转换。我不建议创建到
string
的隐式转换-它们可能会带来更多的痛苦而不是快乐


我还建议不要创建新的
ToString
方法。相反,您应该覆盖由
对象
声明的对象。隐藏方法几乎总是一个坏主意;在某些情况下,您确实希望这样做(例如更改返回类型),但应尽可能避免这样做。

假设
MustHaveString
如下所示:

public void MustHaveString(string arg)
然后简单地说
thing
会导致编译错误,除非
thing
隐式转换为
string
。如果没有隐式转换,您必须执行
thing.ToString()
。但是,如果您的代码如下所示:

string myString = "This is a thing: " + thing;
然后隐式调用
ToString
,因此它是可选的

在大多数情况下,我建议显式调用
ToString
方法,让阅读代码的人清楚地知道发生了什么


编辑:既然这个答案被接受了,我想我还应该提到你应该把你的
ToString()
方法变成一个
覆盖
,而不是一个
新的
。这将导致正常预期的行为,这就是我上面描述的。

假设
MustHaveString
看起来像:

public void MustHaveString(string arg)
然后简单地说
thing
会导致编译错误,除非
thing
隐式转换为
string
。如果没有隐式转换,您必须执行
thing.ToString()
。但是,如果您的代码如下所示:

string myString = "This is a thing: " + thing;
然后隐式调用
ToString
,因此它是可选的

在大多数情况下,我建议显式调用
ToString
方法,让阅读代码的人清楚地知道发生了什么


编辑:既然这个答案被接受了,我想我还应该提到你应该把你的
ToString()
方法变成一个
覆盖
,而不是一个
新的
。这将导致正常预期的行为,这就是我上面描述的。

为什么要声明一个新的
ToString
方法,而不是重写现有的方法?哎呀!(但不,ToString通常不会自动调用。)@JonSkeet,因为根据,重写可用于虚拟方法,而对象中的ToString则不是。@KonradViltersten
ToString
是虚拟的。您的问题尚不清楚。所有引用类型对象都派生自object,并且所有这些对象都有一个
ToString
方法。在创建复杂类型时,
ToString
方法通常会输出调用对象的类名(因为它没有被重写)。你哪里有问题?:)
ToString
当然是虚拟的。看看为什么要声明一个新的
ToString
方法而不是重写现有的方法?哎呀!(但不,ToString通常不会自动调用。)@JonSkeet,因为根据,重写可用于虚拟方法,而对象中的ToString则不是。@KonradViltersten
ToString
是虚拟的。您的问题尚不清楚。所有引用类型对象都派生自object,并且所有这些对象都有一个
ToString
方法。在创建复杂类型时,
ToString
方法通常会输出调用对象的类名(因为它没有被重写)。你哪里有问题?:)
ToString
当然是虚拟的。看见