C# casting:(NewType) 与对象作为 NewType
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Casting: (NewType) vs. Object as NewType
提问by Michael Stum
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?
通常,它们都应该显式转换为指定类型?
采纳答案by Rytmis
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
- You can't use 'as' to convertthings, like numbers to a different representation (float to int, for example).
- 您不能使用“as”运算符强制转换为不接受“null”作为值的类型
- 您不能使用 'as'将数字转换为不同的表示形式(例如,float 到 int)。
And finally, using 'as' vs. the cast operator, you're also saying "I'm not sure if this will succeed."
最后,使用 'as' 与 cast 运算符,您还说“我不确定这是否会成功。”
回答by Rytmis
The parenthetical cast throws an exception if the cast attempt fails. The "as" cast returns null if the cast attempt fails.
如果转换尝试失败,括号转换会引发异常。如果转换尝试失败,“as”转换返回 null。
回答by Steve Willard
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。如果转换失败, () 转换运算符将立即抛出异常。
"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#“as”关键字。如果您指望强制转换成功并且没有准备好接收任何会失败的对象,您应该使用 ()强制转换运算符,以便抛出适当且有用的异常。”
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
回答by denny
Also note that you can only use the as keyword with a reference type or a nullable type
另请注意,您只能将 as 关键字与引用类型或可为空类型一起使用
ie:
IE:
double d = 5.34;
int i = d as int;
will not compile
不会编译
double d = 5.34;
int i = (int)d;
will compile.
会编译。
回答by Nick Berardi
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。
回答by ICR
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.
这就像 Parse 和 TryParse 之间的区别。当您预计它可能会失败时,您可以使用 TryParse,但是当您确信它不会失败时,您可以使用 Parse。
回答by Omer van Kloeten
To expand on Rytmis's comment, you can't use the askeyword for structs (Value Types), as they have no null value.
为了扩展Rytmis 的评论,您不能对结构(值类型)使用as关键字,因为它们没有空值。
回答by Joe
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.aspxis 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”运算符并测试结果是否为空。
回答by Adam Says - Reinstate Monica
For those of you with VB.NET experience, (type) is the same as DirectCast and "as type" is the same as TryCast.
对于那些有 VB.NET 经验的人来说,(type) 与 DirectCast 相同,“as type”与 TryCast 相同。
回答by Keith
All of this applies to reference types, value types cannot use the as
keyword as they cannot be null.
所有这些都适用于引用类型,值类型不能使用as
关键字,因为它们不能为空。
//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:
最佳实践是as
在您不知道类型时使用:
//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.
但是,如果您绝对确定这someObject
是一个实例,SomeClass
则使用强制转换。
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 或更高版本中,泛型意味着您很少需要引用类的无类型实例,因此后者不太常用。