如果我正在创建一个基本上包含字符串消息的类,但也包含与字符串消息相关的有用数据,那么我是否应该覆盖ToString()方法而不是定义强制转换为字符串来获取对象的内部字符串消息?
示例,我有一个名为msg的Message对象,其text == "Hello"
但也包含有关文本来源的信息。我希望Console.WriteLine(msg);
输出"Hello"
。我应该覆盖ToString()
还是将强制转换定义为字符串?
答案 0 :(得分:6)
您应该覆盖ToString
方法。
首先:Console.WriteLine
接受object
并从中调用ToString
方法。
其次:将来某个时候你可能需要创建一个派生自Message
的类。我们来看看:
using System;
using System.IO;
namespace Namespace
{
class StringCastBase
{
public static explicit operator string(StringCastBase o)
{
return "string cast base";
}
}
class StringCastDerived : StringCastBase
{
public static explicit operator string(StringCastDerived o)
{
return "string cast derived";
}
}
class ToStringOverridenBase
{
public override string ToString()
{
return "ToString overriden base";
}
}
class ToStringOverridenDerived : ToStringOverridenBase
{
public override string ToString()
{
return "ToString overriden derived";
}
}
class Programm
{
public static void Main()
{
StringCastBase scb = new StringCastBase();
Console.WriteLine((string)scb);
StringCastBase scd = new StringCastDerived();
Console.WriteLine((string)scd);
ToStringOverridenBase tsob = new ToStringOverridenBase();
Console.WriteLine(tsob);
ToStringOverridenBase tsod = new ToStringOverridenDerived();
Console.WriteLine(tsod);
}
}
}
输出
string cast base
string cast base
ToString覆盖基础
ToString覆盖派生的
由于scd
的静态类型为StringCastBase
,因此将调用StringCastBase
的转换方法(即使 dynamic 类型不是StringCastBase
)。使用虚拟方法ToString
解决了这个问题。
答案 1 :(得分:2)
我想说最好的技巧是让你的类实现一个只读的属性叫(例如)' Text'它提供了主要的字符串。您已经说过该类包含消息文本之外的其他信息 - 实际上,获取文本意味着从您的类中提取该数据。而这正是财产的用途!
为方便起见,我可能还会覆盖ToString() - 以便(a)协助调试,以及(b)确保在其他方法(如Console.WriteLine)调用ToString()时返回有意义的内容() - 他的回答很快就提到了。请记住,ToString()的目的是提供对象的字符串表示,因此您可以考虑是否希望ToString()仅返回主文本,或者是否希望它给出其他信息的一些指示该对象也包含。
在这种情况下我绝对不会使用演员表。你正在做的事情在语义上是错误的。强制转换意味着您将数据从一种类型转换为另一种类型。但那不是你在做什么 - 你正在寻找从课堂中提取特定数据(主要文本)。为此目的使用强制转换可能会让其他开发人员感到困惑。