简体   繁体   English

在 C# 中投射和使用“as”有什么区别?

[英]What is the difference between casting and using "as" in C#?

If there is a difference, what is the difference between the two ways of doing the following cast?如果有区别,做以下演员的两种方式有什么区别?

In this case e is a GridViewRowEventArgs object.在这种情况下, eGridViewRowEventArgs object。

GridView gv = (GridView)e.Row.FindControl("gv"); //first way

GridView gv2 = e.Row.FindControl("gv") as GridView; //second way

The differences are:区别在于:

  • If a cast fails, it throws an InvalidCastException .如果强制转换失败,它会抛出InvalidCastException
  • If the as operator fails, it just returns a null reference.如果as运算符失败,它只会返回 null 引用。
  • You can't use as with non-nullable value types (eg you can't do " o as int ").您不能将as用于不可为空的值类型(例如,您不能使用“ o as int ”)。
  • The cast operator is also used for unboxing. cast 运算符也用于拆箱。 ( as can be used to unbox to a nullable value type.) as可用于拆箱为可空值类型。)
  • The cast operator can also perform user-defined conversions. cast 运算符还可以执行用户定义的转换。

EDIT: I've written elsewhere about when I feel it's appropriate to use which operator.编辑:我在其他地方写过我觉得什么时候适合使用哪个运算符。 That might be worth a read...那可能值得一读……

What isn't mentioned in the above answers is intent -- why are you performing the conversion, and (more importantly) what happens on the lines after the conversion?上述答案中没有提到的是意图——你为什么要执行转换,以及(更重要的是)转换后的行会发生什么?

For example, I've seen code similar to the following a number of times:例如,我多次看到类似以下的代码:

if ((foo as SomeType).SomeMethod()) { /*... */ }

This could be compared to the cast-using version:这可以与使用演员的版本进行比较:

if (((SomeType) foo).SomeMethod()) { /*... */ }

So, which of these is better?那么,这些中哪个更好呢?

The cast is.演员是。

Using as will result in a NullReferenceException if the conversion fails.如果转换失败,使用as将导致NullReferenceException

Using a cast will result in an InvalidCastException if the conversion fails.如果转换失败,使用强制转换将导致InvalidCastException

Now tell me, which is a more useful exception for debugging?现在告诉我,哪个对调试更有用? A NullReferenceException , which could be produced by nearly anything, or an InvalidCastException , which lets you know what actually went wrong? NullReferenceException几乎可以由任何东西产生,或者InvalidCastException可以让您知道实际出了什么问题?

Thus, only use as if the conversion is actually optional (meaning that there must be a null check before using the variable).因此,as转换实际上是可选的情况下使用(意味着在使用变量之前必须进行null检查)。 Otherwise, use a cast, thus making your intentions more explicit.否则,请使用演员表,从而使您的意图更加明确。

In general, the difference between a static cast and "as", is that the cast will throw an Exception if it fails, whereas "as" will just set the variable to null.一般来说,static 转换和“as”之间的区别在于,转换失败时会抛出异常,而“as”只会将变量设置为 null。

The "as" statement basically makes an attempt to cast the variable, and returns null if it fails rather than throwing an exception. “as”语句基本上尝试强制转换变量,如果失败而不是抛出异常,则返回 null。 As such, the value to which you're casting must be nullable - a reference type or a nullable primitive.因此,您要转换的值必须是可为空的——引用类型或可为空的原语。 In your example, you'd have to do:在您的示例中,您必须执行以下操作:

int? i2 = o as int;

or it won't compile.或者它不会编译。

The safe cast as安全演员

variable as type

does the same as

(variable is type) ? (type)variable : (type)null

and will not work for value types.并且不适用于值类型。

If you however used a reference type say Table the first one would raise InvalidCastException in case o was not assignable to Table and the second would just return null.但是,如果您使用引用类型,例如 Table,则第一个将引发 InvalidCastException,以防 o 无法分配给 Table,而第二个只会返回 null。

Apart from the issue which Jon pointed out, the as keyword effectively casts o as SomeClass .除了 Jon 指出的问题之外, as关键字有效地将o转换为SomeClass If o isn't derived from SomeClass it returns null .如果o不是从SomeClass派生的,则返回null Whereas a simple cast would throw an exception.而简单的演员表会抛出异常。

SomeClass i2 = o as SomeClass;

becomes变成

SomeClass i2;
if (o is SomeClass)
    i2 = (SomeClass)o;
else
    i2 = null;

I might be stating the obvious here, but one thing that you get with the 'as' cast is, that you are guaranteed to end up with an object of the type you requested.我可能会在这里说明显而易见的事情,但是您使用“as”演员得到的一件事是,您可以保证最终得到您请求的类型的 object。 This comes in handy in certain situations.这在某些情况下会派上用场。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM