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