直接投射vs'as'运营商?

考虑下面的代码:

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。 否则,即使onull ,也将o赋给s

string s = o as string; // 2

分配nulls ,如果o是不是一个string ,或者onull 。 出于这个原因,你不能将它与值类型一起使用(在这种情况下,操作符永远不能返回null )。 否则,将o赋给s

string s = o.ToString(); // 3

如果onull则会导致NullReferenceException。 无论o是什么类型,都将o.ToString()返回给s


使用1进行大多数转换 - 这很简单直接。 我倾向于几乎从不使用2,因为如果事情不是正确的类型,我通常会期望发生异常。 我只看到需要使用错误代码的糟糕设计库(例如,返回null =错误,而不是使用例外)的返回null类型的功能。

3不是强制转换,只是一个方法调用。 在需要非字符串对象的字符串表示时使用它。


  • 当某件事一定是另一件事情时使用。
  • 当某件事可能是另一件事时使用。
  • 当你不关心它是什么时使用,但你只是想使用可用的字符串表示。

  • 这实际上取决于你是否知道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。 由于几乎每条线都将一个变量解除引用并可能抛出一个变量,因此这些变量往往更常见,并且一旦发生在野外就很难追查到。 另一方面,如果你试图转换为值类型(任何原始类型或诸如DateTime之类的结构),则必须使用直接投射 - 这as行不通的。

    在转换为字符串的特殊情况下,每个对象都有一个ToString ,所以如果o不为null,并且您认为ToString方法可以做到您想要的,则您的第三个方法可能没问题。

    链接地址: http://www.djcxy.com/p/2023.html

    上一篇: Direct casting vs 'as' operator?

    下一篇: Does finally always execute in Java?