C# 直接转换 vs 'as' 运算符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/132445/
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
Direct casting vs 'as' operator?
提问by nullDev
Consider the following code:
考虑以下代码:
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
}
What is the difference between the three types of casting (okay, the 3rd one is not a casting, but you get the intent). Which one should be preferred?
三种类型的铸造有什么区别(好吧,第三种不是铸造,但你明白了意图)。应该首选哪一个?
采纳答案by Sander
string s = (string)o; // 1
Throws InvalidCastExceptionif o
is not a string
. Otherwise, assigns o
to s
, even if o
is null
.
如果不是 ,则抛出InvalidCastException。否则,分配给,即使是。o
string
o
s
o
null
string s = o as string; // 2
Assigns null
to s
if o
is not a string
or if o
is null
. For this reason, you cannot use it with value types (the operator could never return null
in that case). Otherwise, assigns o
to s
.
分配null
到s
如果o
不是string
,或者o
是null
。出于这个原因,您不能将它与值类型一起使用(null
在这种情况下,运算符永远不会返回)。否则,分配o
给s
。
string s = o.ToString(); // 3
Causes a NullReferenceExceptionif o
is null
. Assigns whatever o.ToString()
returns to s
, no matter what type o
is.
如果是,则导致NullReferenceException。分配任何返回给,无论是什么类型。o
null
o.ToString()
s
o
Use 1 for most conversions - it's simple and straightforward. I tend to almost never use 2 since if something is not the right type, I usually expect an exception to occur. I have only seen a need for this return-null type of functionality with badly designed libraries which use error codes (e.g. return null = error, instead of using exceptions).
对大多数转换使用 1 - 它简单明了。我几乎从不使用 2,因为如果某些东西的类型不正确,我通常会期望发生异常。我只看到使用错误代码(例如,返回 null = 错误,而不是使用异常)的设计糟糕的库需要这种返回空类型的功能。
3 is not a cast and is just a method invocation. Use it for when you need the string representation of a non-string object.
3 不是强制转换,只是一个方法调用。当您需要非字符串对象的字符串表示时使用它。
回答by Sergio Acosta
'as' is based on 'is', which is a keyword that checks at runtime if the object is polimorphycally compatible (basically if a cast can be made) and returns null if the check fails.
“as”基于“is”,它是一个关键字,用于在运行时检查对象是否多态兼容(基本上如果可以进行强制转换)并在检查失败时返回 null。
These two are equivalent:
这两个是等价的:
Using 'as':
使用“作为”:
string s = o as string;
Using 'is':
使用“是”:
if(o is string)
s = o;
else
s = null;
On the contrary, the c-style cast is made also at runtime, but throws an exception if the cast cannot be made.
相反,c 样式的强制转换也在运行时进行,但如果无法进行强制转换则抛出异常。
Just to add an important fact:
补充一个重要的事实:
The 'as' keyword only works with reference types. You cannot do:
“as”关键字仅适用于引用类型。你不能这样做:
// I swear i is an int
int number = i as int;
In those cases you have to use casting.
在这些情况下,您必须使用强制转换。
回答by Blair Conrad
It really depends on whether you know if o
is a string and what you want to do with it. If your comment means that o
really really is a string, I'd prefer the straight (string)o
cast - it's unlikely to fail.
这真的取决于你是否知道 ifo
是一个字符串以及你想用它做什么。如果您的评论意味着它o
真的是一个字符串,我更喜欢直接转换(string)o
- 它不太可能失败。
The biggest advantage of using the straight cast is that when it fails, you get an InvalidCastException, which tells you pretty much what went wrong.
使用直接转换的最大优点是,当它失败时,您会得到一个InvalidCastException,它几乎可以告诉您出了什么问题。
With the as
operator, if o
isn't a string, s
is set to null
, which is handy if you're unsure and want to test s
:
使用as
运算符,如果o
不是字符串,s
则设置为null
,如果您不确定并想要测试,这很方便s
:
string s = o as string;
if ( s == null )
{
// well that's not good!
gotoPlanB();
}
However, if you don't perform that test, you'll use s
later and have a NullReferenceExceptionthrown. These tend to be more common and a lotharder to track down once they happens out in the wild, as nearly every line dereferences a variable and may throw one. On the other hand, if you're trying to cast to a value type (any primitive, or structs such as DateTime), you have to use the straight cast - the as
won't work.
但是,如果您不执行该测试,您将在稍后使用s
并抛出NullReferenceException。这些往往是比较常见和很多难以追查,一旦他们在野外发生了,因为几乎每行取消引用变量,可能会抛出一个。另一方面,如果您尝试转换为值类型(任何基元或结构,例如DateTime),则必须使用直接转换 - 这as
将不起作用。
In the special case of converting to a string, every object has a ToString
, so your third method may be okay if o
isn't null and you think the ToString
method might do what you want.
在转换为字符串的特殊情况下,每个对象都有一个ToString
,因此如果o
不是 null 并且您认为该ToString
方法可能会执行您想要的操作,则您的第三个方法可能没问题。
回答by Rob
"(string)o" will result in an InvalidCastException as there's no direct cast.
"(string)o" 将导致 InvalidCastException,因为没有直接转换。
"o as string" will result in s being a null reference, rather than an exception being thrown.
“o as string”将导致 s 为空引用,而不是抛出异常。
"o.ToString()" isn't a cast of any sort per-se, it's a method that's implemented by object, and thus in one way or another, by every class in .net that "does something" with the instance of the class it's called on and returns a string.
"o.ToString()" 本身并不是任何类型的强制转换,它是一种由对象实现的方法,因此以一种或另一种方式,由 .net 中的每个类对实例“做某事”它被调用的类并返回一个字符串。
Don't forget that for converting to string, there's also Convert.ToString(someType instanceOfThatType) where someType is one of a set of types, essentially the frameworks base types.
不要忘记为了转换为字符串,还有 Convert.ToString(someType instanceOfThatType) ,其中 someType 是一组类型之一,本质上是框架的基本类型。
回答by Quibblesome
string s = (string)o;
Use when something should definitelybe the other thing.string s = o as string;
Use when something might bethe other thing.string s = o.ToString();
Use when you don't care what it is but you just want to use the available string representation.
string s = (string)o;
当某事 绝对应该是另一件事时使用。string s = o as string;
当某事可能是另一件事时使用。string s = o.ToString();
当您不在乎它是什么但只想使用可用的字符串表示时使用。
回答by Joel in G?
2 is useful for casting to a derived type.
2 对于转换为派生类型很有用。
Suppose ais an Animal:
假设a是一个动物:
b = a as Badger;
c = a as Cow;
if (b != null)
b.EatSnails();
else if (c != null)
c.EatGrass();
will get afed with a minimum of casts.
将得到一个用最少的铸件送入。
回答by Mark Cidade
If you already know what type it can cast to, use a C-style cast:
如果您已经知道它可以转换为什么类型,请使用 C 样式转换:
var o = (string) iKnowThisIsAString;
Note that only with a C-style cast can you perform explicit type coercion.
请注意,只有使用 C 风格的强制转换才能执行显式类型强制。
If you don't know whether it's the desired type and you're going to use it if it is, use askeyword:
如果您不知道它是否是所需的类型并且您打算使用它,请使用as关键字:
var s = o as string;
if (s != null) return s.Replace("_","-");
//or for early return:
if (s==null) return;
Note that aswill not call any type conversion operators. It will only be non-null if the object is not null and natively of the specified type.
请注意as不会调用任何类型转换运算符。如果对象不为 null 且本机为指定类型,则它只会为非 null。
Use ToString() to get a human-readable string representation of any object, even if it can't cast to string.
使用 ToString() 获取任何对象的人类可读的字符串表示形式,即使它不能转换为字符串。
回答by Chris S
string s = o as string; // 2
Is prefered, as it avoids the performance penalty of double casting.
首选,因为它避免了双重铸造的性能损失。
回答by Glenn Slaven
The as keyword is good in asp.net when you use the FindControl method.
当您使用 FindControl 方法时, as 关键字在 asp.net 中很好。
Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
...
}
This means you can operate on the typed variable rather then having to then cast it from object
like you would with a direct cast:
这意味着您可以对类型化变量进行操作,而不必object
像使用直接转换那样对其进行转换:
object linkObj = this.FindControl("linkid");
if (link != null)
{
Hyperlink link = (Hyperlink)linkObj;
}
It's not a huge thing, but it saves lines of code and variable assignment, plus it's more readable
这不是什么大事,但它节省了代码行和变量赋值,而且更具可读性
回答by Brady Moritz
According to experiments run on this page: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
根据在此页面上运行的实验:http: //www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(this page is having some "illegal referrer" errors show up sometimes, so just refresh if it does)
(此页面有时会出现一些“非法引荐来源”错误,因此如果确实如此,请刷新)
Conclusion is, the "as" operator is normally faster than a cast. Sometimes by many times faster, sometimes just barely faster.
结论是,“as”运算符通常比强制转换更快。有时快很多倍,有时只是快一点。
I peronsonally thing "as" is also more readable.
我个人认为“作为”也更具可读性。
So, since it is both faster and "safer" (wont throw exception), and possibly easier to read, I recommend using "as" all the time.
因此,由于它既更快又“更安全”(不会抛出异常),并且可能更易于阅读,因此我建议始终使用“as”。