考虑以下代码:
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
方法可以完成您想做的事情,那么您的第三个方法就可以了。