考虑以下代码:

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
}

三种类型的施法有什么区别(好吧,第三种不是施法,但你明白了意图)。应该首选哪一种?


当前回答

根据本页上运行的实验:http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as

(此页面有时会显示一些“非法引用者”错误,因此如果出现,请刷新)

结论是,“as”运算符通常比强制转换快。有时速度快很多倍,有时仅仅快不了几倍。

我个人认为“as”也更可读。

因此,由于它既快又“安全”(不会抛出异常),而且可能更容易阅读,我建议一直使用“as”。

其他回答

我想提请注意as操作员的以下细节:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as

注意,as运算符仅执行参考转换,可空转换和装箱转换。as运算符不能执行其他转换,例如用户定义的转换应改为使用强制转换表达式来执行。

“as”基于“is”,这是一个关键字,用于在运行时检查对象是否与polimorphyly兼容(基本上,如果可以进行强制转换),如果检查失败,则返回null。

这两者是等价的:

使用“as”:

string s = o as string;

使用“is”:

if(o is string) 
    s = o;
else
    s = null;

相反,c样式转换也在运行时进行,但如果无法进行转换,则会引发异常。

只是为了补充一个重要的事实:

“as”关键字仅适用于引用类型。您不能执行以下操作:

// I swear i is an int
int number = i as int;

在这种情况下,你必须使用铸造。

根据本页上运行的实验:http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as

(此页面有时会显示一些“非法引用者”错误,因此如果出现,请刷新)

结论是,“as”运算符通常比强制转换快。有时速度快很多倍,有时仅仅快不了几倍。

我个人认为“as”也更可读。

因此,由于它既快又“安全”(不会抛出异常),而且可能更容易阅读,我建议一直使用“as”。

当试图获取任何(任何类型)可能为空的字符串表示时,我更喜欢下面的代码行。它很紧凑,它调用ToString(),并正确处理空值。如果o为空,则s将包含String.Empty。

String s = String.Concat(o);

使用直接转换字符串s=(string)o;如果在应用程序的逻辑上下文中,字符串是唯一有效的类型。使用这种方法,您将获得InvalidCastException并实现快速失败的原则。您的逻辑将受到保护,不会进一步传递无效类型,或者如果用作运算符,将获得NullReferenceException。

如果逻辑需要几个不同的类型,则将字符串s=o转换为字符串;并检查null或use-is运算符。

C#7.0中出现了新的酷炫功能,以简化转换,并检查模式匹配:

if(o is string s)
{
  // Use string variable s
}

or

switch (o)
{
  case int i:
     // Use int variable i
     break;
  case string s:
     // Use string variable s
     break;
 }