Casting:(NewType)与Object作为NewType

Possible Duplicate:
Casting vs using the 'as' keyword in the CLR

这两个演员之间的区别究竟是什么?

SomeClass sc = (SomeClass)SomeObject;
SomeClass sc2 = SomeObject as SomeClass;

通常情况下,他们都应该明确转换为指定的类型?

0
额外 编辑
意见: 1
这是有趣的,因为这一个是3个月前发布:)但另一个有更详细的答案。
额外 作者 Michael Stum,
另请参见 stackoverflow.com/questions/496096/… 。这是第一个,但那个有一个很好的答案。
额外 作者 Jay Bazuzi,
你已经发布了第二个最早的问题,它是另一个最重要的问题(第一个被锁定)!恭喜,我猜?
额外 作者 gparyani,

12 答案

这里有一个很好的方法来记住他们每个人在试图决定哪种方式更适合我的情况时使用的过程。

DateTime i = (DateTime)value;
// is like doing
DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);

而下一个应该很容易猜到它的作用

DateTime i = value as DateTime;

在第一种情况下,如果无法强制转换值,那么在第二种情况下如果无法强制转换异常,则将i设置为空。

所以在第一种情况下,如果在第二次强制转换失败后进行软停止,您可能会遇到困难,您可能会在稍后遇到NullReferenceException。

0
额外
0
额外

这就像Parse和TryParse的区别。如果您期望可能会失败,则使用TryParse,但是如果您有足够的保证,则不会因使用Parse而失败。

0
额外

另请注意,您只能将as关键字与引用类型或可为空的类型一起使用

即:

double d = 5.34;
int i = d as int;

不会编译

double d = 5.34;
int i = (int)d;

将编译。

0
额外
因为铸件不转换
额外 作者 CiNN,

如果源类型不能转换为目标类型,前者将抛出异常。后者将导致sc2为空引用,但也不例外。

[编辑]

我的原始答案肯定是最明显的区别,但是作为Eric Lippert 指出,它不是唯一的一个。其他差异包括:

  • 您不能使用'as'操作符来转换为不接受'null'作为值的类型
  • 您不能使用'as'来转换 ,例如将数字转换为不同的表示形式(例如,float为int)。

最后,使用'as'和演员,你也会说'我不确定这是否会成功。“

0
额外

他们会抛出不同的例外。点击 ():NullReferenceException
如:InvalidCastException
这可能有助于调试。

“as”关键字尝试转换对象,如果转换失败,则以无提示方式返回null。如果转换失败,()转换运算符将立即抛出异常。

“只有在非特殊情况下,您才需要使用C#”as“作为关键字,如果您希望演员成功并且没有准备好接收任何失败的对象,则应该使用()转换操作符,以便引发适当和有用的异常。“

For code examples and a further explanation: http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

0
额外
(-1),因为不会抛出InvalidCastException。
额外 作者 Keith,

所有这些都适用于引用类型,值类型不能使用 as 关键字,因为它们不能为null。

//if I know that SomeObject is an instance of SomeClass
SomeClass sc = (SomeClass) someObject;


//if SomeObject *might* be SomeClass
SomeClass sc2 = someObject as SomeClass;

演员的语法更快,但只有成功时,失败速度要慢得多。

最佳做法是在不知道类型时使用作为

//we need to know what someObject is
SomeClass sc;
SomeOtherClass soc;

//use as to find the right type
if( ( sc = someObject as SomeClass ) != null ) 
{
    //do something with sc
}
else if ( ( soc = someObject as SomeOtherClass ) != null ) 
{
    //do something with soc
}

但是,如果您确定 someObjectSomeClass 的一个实例,则使用cast。

在.Net 2或以上的泛型意味着你很少需要有一个非类型的引用类的实例,所以后者不太经常使用。

0
额外

那么'as'操作符“帮助”你将问题埋在更低的地方,因为当它提供了一个不兼容的实例时它将返回null,也许你会将它传递给一个将它传递给另一个的方法等等,最后你会得到一个NullReferenceException,这将使你的调试更加困难。

不要滥用它。在99%的情况下,直接操作的操作员更好。

0
额外
非常合理的建议。读者请考虑这一点。
额外 作者 mbadawi23,

要扩展 Rytmis的评论,您不能使用 as 关键字的结构(值类型),因为它们没有空值。

0
额外

当演员失败时,使用“as”进行类型转换当然快得多,因为它避免了抛出异常的代价。

但是演员成功后它不会更快。 http://www.codeproject.com/KB/cs/csharpcasts.aspx 具有误导性,因为它不能解释它所测量的内容。

底线是:

  • 如果您希望演员成功(即失败是例外),请使用演员表。

  • 如果您不知道它是否会成功,请使用“as”运算符并测试结果为null。

0
额外

两种方法之间的区别在于第一个((SomeClass)obj)可能导致类型转换器被调用。

0
额外

对于那些有VB.NET经验的人,(类型)与DirectCast相同,“as type”与TryCast相同。

0
额外