考虑以下代码:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}三种类型的转换之间有什么区别(好吧,第三个类型不是转换,但是您有意图)。应该首选哪一个?
string s = (string)o; // 1如果o不是string则抛出InvalidCastException 。否则,将o分配给s ,即使o为null 。
string s = o as string; // 2分配null到s ,如果o是不是一个string ,或者o为null 。因此,您不能将其与值类型一起使用(在这种情况下null否则,将o分配给s 。
string s = o.ToString(); // 3如果o为null则导致NullReferenceException 。 o是什么类型,都将o.ToString()返回的值s
对于大多数转化,请使用 1 - 简单明了。我倾向于几乎从不使用 2,因为如果某些类型不正确,我通常希望发生异常。我只看到这种返回 null 类型的功能需要使用错误代码(例如,返回 null = 错误,而不是使用异常)的错误设计的库。
3 不是强制转换,而只是方法调用。在需要非字符串对象的字符串表示形式时使用它。
string s = (string)o;绝对应该是另一回事时使用。string s = o as string;当某件事可能是另一回事时使用。string s = o.ToString();当您不在乎它是什么但只想使用可用的字符串表示形式时使用。这实际上取决于您是否知道o是否为字符串以及您要如何处理。如果您的评论表示o确实是一个字符串,则我希望使用直接(string)o强制转换 - 不太可能失败。
使用直接强制类型转换的最大优点是,当它失败时,您将收到 InvalidCastException,它可以告诉您几乎所有出了什么问题。
使用as运算符,如果o不是字符串, s设置为null ,如果不确定并想要测试s ,则非常方便:
string s = o as string;
if ( s == null )
{
// well that's not good!
gotoPlanB();
}但是,如果不执行该测试,则稍后将使用s并引发NullReferenceException。这些往往是更常见,很多难以追查,一旦他们在野外发生了,因为几乎每行取消引用变量,可能会抛出一个。在另一方面,如果你想投的值类型(任何原始的,或结构如日期时间),你必须使用直投 - 将as将无法正常工作。
在转换为字符串的特殊情况下,每个对象都有一个ToString o不为 null,并且您认为ToString方法可以完成您想做的事情,那么您的第三个方法就可以了。