类型转换:(NewType) vs对象为NewType [duplicate]

时间:2022-05-21 22:28:32

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

可能的重复:在CLR中使用“as”关键字铸造vs

What is actually the difference between these two casts?

这两个类型之间的区别是什么?

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

Normally, they should both be explicit casts to the specified type?

通常,它们都应该显式地转换到指定类型?

13 个解决方案

#1


83  

The former will throw an exception if the source type can't be cast to the target type. The latter will result in sc2 being a null reference, but no exception.

如果无法将源类型转换为目标类型,则前者将抛出异常。后者将导致sc2成为空引用,但没有例外。

[Edit]

(编辑)

My original answer is certainly the most pronounced difference, but as Eric Lippert points out, it's not the only one. Other differences include:

我最初的答案当然是最明显的区别,但正如Eric Lippert所指出的,这并不是唯一的答案。其他的差异包括:

  • You can't use the 'as' operator to cast to a type that doesn't accept 'null' as a value
  • 不能使用“as”操作符将类型转换为不接受“null”作为值的类型
  • You can't use 'as' to convert things, like numbers to a different representation (float to int, for example).
  • 你不能使用“as”来转换事物,比如数字到不同的表示形式(例如,float to int)。

And finally, using 'as' vs. the cast operator, you're also saying "I'm not sure if this will succeed."

最后,使用“as”和“cast”运算符,你也可以说“我不确定这是否会成功”。

#2


27  

Also note that you can only use the as keyword with a reference type or a nullable type

还要注意的是,您只能对引用类型或可空类型使用as关键字

ie:

即:

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

will not compile

将不会编译

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

will compile.

将编译。

#3


9  

Typecasting using "as" is of course much faster when the cast fails, as it avoids the expense of throwing an exception.

当转换失败时,使用“as”进行类型转换当然要快得多,因为这样可以避免抛出异常的代价。

But it is not faster when the cast succeeds. The graph at http://www.codeproject.com/KB/cs/csharpcasts.aspx is misleading because it doesn't explain what it's measuring.

但是当演员成功的时候并不是更快。http://www.codeproject.com/KB/cs/csharpcasts.aspx上的图表具有误导性,因为它没有解释它测量的是什么。

The bottom line is:

底线是:

  • If you expect the cast to succeed (i.e. a failure would be exceptional), use a cast.

    如果你希望施法成功(比如失败是例外),使用施法。

  • If you don't know if it will succeed, use the "as" operator and test the result for null.

    如果您不知道它是否会成功,请使用“as”操作符并测试null的结果。

#4


5  

A difference between the two approaches is that the the first ((SomeClass)obj) may cause a type converter to be called.

这两种方法的不同之处在于,第一个((SomeClass)obj)可能导致一个类型转换器被调用。

#5


4  

Here is a good way to remember the process that each of them follow that I use when trying to decide which is better for my circumstance.

这里有一个很好的方法来记住我在决定哪种方法更适合我的环境时所遵循的过程。

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

and the next should be easy to guess what it does

下一个应该很容易猜出来

DateTime i = value as DateTime;

in the first case if the value cannot be cast than an exception is thrown in the second case if the value cannot be cast, i is set to null.

在第一种情况下,如果值不能被强制转换,那么在第二种情况下,如果值不能强制转换,则将i设置为null。

So in the first case a hard stop is made if the cast fails in the second cast a soft stop is made and you might encounter a NullReferenceException later on.

因此,在第一种情况下,如果在第二次强制转换中强制停止,就会进行软停止,您可能会在稍后遇到NullReferenceException。

#6


4  

Well the 'as' operator "helps" you bury your problem way lower because when it is provided an incompatible instance it will return null, maybe you'll pass that to a method which will pass it to another and so on and finally you'll get a NullReferenceException which will make your debugging harder.

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

Don't abuse it. The direct cast operator is better in 99% of the cases.

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

#7


3  

To expand on Rytmis's comment, you can't use the as keyword for structs (Value Types), as they have no null value.

要扩展Rytmis的注释,不能使用as关键字作为structs(值类型),因为它们没有null值。

#8


2  

All of this applies to reference types, value types cannot use the as keyword as they cannot be null.

所有这些都适用于引用类型,值类型不能使用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;

The cast syntax is quicker, but only when successful, it's much slower to fail.

强制转换语法更快,但只有在成功时,失败才会慢得多。

Best practice is to use as when you don't know the type:

最好的做法是在你不知道类型的时候使用:

//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
}

However if you are absolutely sure that someObject is an instance of SomeClass then use cast.

但是,如果您绝对确定某个对象是一个SomeClass的实例,那么就使用cast。

In .Net 2 or above generics mean that you very rarely need to have an un-typed instance of a reference class, so the latter is less often used.

在。net 2或以上的泛型中,您很少需要引用类的非类型化实例,所以后者很少被使用。

#9


1  

The parenthetical cast throws an exception if the cast attempt fails. The "as" cast returns null if the cast attempt fails.

如果强制转换失败,括号中的强制转换将抛出异常。如果转换尝试失败,则“as”转换返回null。

#10


1  

They'll throw different exceptions.
() : NullReferenceException
as : InvalidCastException
Which could help for debugging.

他们会把不同的异常。(): NullReferenceException as: InvalidCastException,可以帮助调试。

The "as" keyword attempts to cast the object and if the cast fails, null is returned silently. The () cast operator will throw an exception immediately if the cast fails.

“as”关键字尝试强制转换对象,如果强制转换失败,则以静默方式返回null。如果cast失败,则()cast操作符将立即抛出异常。

"Only use the C# "as" keyword where you are expecting the cast to fail in a non-exceptional case. If you are counting on a cast to succeed and are unprepared to receive any object that would fail, you should use the () cast operator so that an appropriate and helpful exception is thrown."

“只使用c#”作为“关键字,在非例外情况下,您希望强制转换失败”。如果您期望强制类型转换成功,并且没有准备接收任何可能失败的对象,那么应该使用()强制类型转换操作符,以便抛出适当的、有用的异常。

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

有关代码示例和进一步解释:http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

#11


1  

It's like the difference between Parse and TryParse. You use TryParse when you expect it might fail, but when you have strong assurance it won't fail you use Parse.

这就像解析和TryParse的区别。当您预期它可能会失败时,您将使用TryParse,但是当您有强烈的保证它不会失败时,您将使用Parse。

#12


1  

For those of you with VB.NET experience, (type) is the same as DirectCast and "as type" is the same as TryCast.

有VB的同学。NET experience, (type)与DirectCast相同,“as type”与TryCast相同。

#13


1  

And for the sake of completeness, Eric Lippert has a blog post about the difference and some caveats.

为了完整起见,Eric Lippert有一个关于差异和一些警告的博客文章。

#1


83  

The former will throw an exception if the source type can't be cast to the target type. The latter will result in sc2 being a null reference, but no exception.

如果无法将源类型转换为目标类型,则前者将抛出异常。后者将导致sc2成为空引用,但没有例外。

[Edit]

(编辑)

My original answer is certainly the most pronounced difference, but as Eric Lippert points out, it's not the only one. Other differences include:

我最初的答案当然是最明显的区别,但正如Eric Lippert所指出的,这并不是唯一的答案。其他的差异包括:

  • You can't use the 'as' operator to cast to a type that doesn't accept 'null' as a value
  • 不能使用“as”操作符将类型转换为不接受“null”作为值的类型
  • You can't use 'as' to convert things, like numbers to a different representation (float to int, for example).
  • 你不能使用“as”来转换事物,比如数字到不同的表示形式(例如,float to int)。

And finally, using 'as' vs. the cast operator, you're also saying "I'm not sure if this will succeed."

最后,使用“as”和“cast”运算符,你也可以说“我不确定这是否会成功”。

#2


27  

Also note that you can only use the as keyword with a reference type or a nullable type

还要注意的是,您只能对引用类型或可空类型使用as关键字

ie:

即:

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

will not compile

将不会编译

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

will compile.

将编译。

#3


9  

Typecasting using "as" is of course much faster when the cast fails, as it avoids the expense of throwing an exception.

当转换失败时,使用“as”进行类型转换当然要快得多,因为这样可以避免抛出异常的代价。

But it is not faster when the cast succeeds. The graph at http://www.codeproject.com/KB/cs/csharpcasts.aspx is misleading because it doesn't explain what it's measuring.

但是当演员成功的时候并不是更快。http://www.codeproject.com/KB/cs/csharpcasts.aspx上的图表具有误导性,因为它没有解释它测量的是什么。

The bottom line is:

底线是:

  • If you expect the cast to succeed (i.e. a failure would be exceptional), use a cast.

    如果你希望施法成功(比如失败是例外),使用施法。

  • If you don't know if it will succeed, use the "as" operator and test the result for null.

    如果您不知道它是否会成功,请使用“as”操作符并测试null的结果。

#4


5  

A difference between the two approaches is that the the first ((SomeClass)obj) may cause a type converter to be called.

这两种方法的不同之处在于,第一个((SomeClass)obj)可能导致一个类型转换器被调用。

#5


4  

Here is a good way to remember the process that each of them follow that I use when trying to decide which is better for my circumstance.

这里有一个很好的方法来记住我在决定哪种方法更适合我的环境时所遵循的过程。

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

and the next should be easy to guess what it does

下一个应该很容易猜出来

DateTime i = value as DateTime;

in the first case if the value cannot be cast than an exception is thrown in the second case if the value cannot be cast, i is set to null.

在第一种情况下,如果值不能被强制转换,那么在第二种情况下,如果值不能强制转换,则将i设置为null。

So in the first case a hard stop is made if the cast fails in the second cast a soft stop is made and you might encounter a NullReferenceException later on.

因此,在第一种情况下,如果在第二次强制转换中强制停止,就会进行软停止,您可能会在稍后遇到NullReferenceException。

#6


4  

Well the 'as' operator "helps" you bury your problem way lower because when it is provided an incompatible instance it will return null, maybe you'll pass that to a method which will pass it to another and so on and finally you'll get a NullReferenceException which will make your debugging harder.

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

Don't abuse it. The direct cast operator is better in 99% of the cases.

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

#7


3  

To expand on Rytmis's comment, you can't use the as keyword for structs (Value Types), as they have no null value.

要扩展Rytmis的注释,不能使用as关键字作为structs(值类型),因为它们没有null值。

#8


2  

All of this applies to reference types, value types cannot use the as keyword as they cannot be null.

所有这些都适用于引用类型,值类型不能使用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;

The cast syntax is quicker, but only when successful, it's much slower to fail.

强制转换语法更快,但只有在成功时,失败才会慢得多。

Best practice is to use as when you don't know the type:

最好的做法是在你不知道类型的时候使用:

//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
}

However if you are absolutely sure that someObject is an instance of SomeClass then use cast.

但是,如果您绝对确定某个对象是一个SomeClass的实例,那么就使用cast。

In .Net 2 or above generics mean that you very rarely need to have an un-typed instance of a reference class, so the latter is less often used.

在。net 2或以上的泛型中,您很少需要引用类的非类型化实例,所以后者很少被使用。

#9


1  

The parenthetical cast throws an exception if the cast attempt fails. The "as" cast returns null if the cast attempt fails.

如果强制转换失败,括号中的强制转换将抛出异常。如果转换尝试失败,则“as”转换返回null。

#10


1  

They'll throw different exceptions.
() : NullReferenceException
as : InvalidCastException
Which could help for debugging.

他们会把不同的异常。(): NullReferenceException as: InvalidCastException,可以帮助调试。

The "as" keyword attempts to cast the object and if the cast fails, null is returned silently. The () cast operator will throw an exception immediately if the cast fails.

“as”关键字尝试强制转换对象,如果强制转换失败,则以静默方式返回null。如果cast失败,则()cast操作符将立即抛出异常。

"Only use the C# "as" keyword where you are expecting the cast to fail in a non-exceptional case. If you are counting on a cast to succeed and are unprepared to receive any object that would fail, you should use the () cast operator so that an appropriate and helpful exception is thrown."

“只使用c#”作为“关键字,在非例外情况下,您希望强制转换失败”。如果您期望强制类型转换成功,并且没有准备接收任何可能失败的对象,那么应该使用()强制类型转换操作符,以便抛出适当的、有用的异常。

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

有关代码示例和进一步解释:http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html

#11


1  

It's like the difference between Parse and TryParse. You use TryParse when you expect it might fail, but when you have strong assurance it won't fail you use Parse.

这就像解析和TryParse的区别。当您预期它可能会失败时,您将使用TryParse,但是当您有强烈的保证它不会失败时,您将使用Parse。

#12


1  

For those of you with VB.NET experience, (type) is the same as DirectCast and "as type" is the same as TryCast.

有VB的同学。NET experience, (type)与DirectCast相同,“as type”与TryCast相同。

#13


1  

And for the sake of completeness, Eric Lippert has a blog post about the difference and some caveats.

为了完整起见,Eric Lippert有一个关于差异和一些警告的博客文章。