普通类型转换和使用“AS”关键字有什么区别?

9
8个回答

20

使用as关键字可以在对象类型错误时优雅地失败,结果值会变为null。普通的强制类型转换会抛出InvalidCastException异常:

object x = new object();
string y = x as string; // y == null
string z = (string)x; // InvalidCastException

7
这两个运算符的用例表面上看起来相似,但语义上却非常不同。强制转换向读者传达了“我确信这种转换是合法的,如果我错了,我愿意接受运行时异常”的信息。而“as”运算符传达的是“我不知道这种转换是否合法;我们将尝试一下,看看情况如何”的信息。
有关此主题的更多信息,请参阅我的文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx


1
它可以进行通信,但不一定。当我确定转换会起作用时,我使用as关键字,因为我更喜欢看到:(myobj as MyType).SomeProperty而不是((MyType)myobj).SomeProperty。在这种情况下,我所做的方式表明,如果运行时出现问题,我愿意接受NullReferenceException。只是想指出这是一种风格上的事情。 - jasonh
2
@jasonh - 对我来说,使用 as 的方式在风格上看起来不太对。这会让我想知道为什么没有进行强制转换。此外,无效的强制转换异常会比空引用异常更快地引导开发人员找到问题。我更喜欢 Eric 的风格。 - Jeffrey L Whitledge

1

as转换永远不会抛出异常,而通常的转换可能会。

Object a = new Object();
String b = a as String;
if(b != null) // always false for this example.
{}

1

普通类型转换可能会返回IllegalTypeCast异常,而as在这种情况下将返回null


1
((Class2) obj)  // Throws exception when the casting cannot be made

Class2 C = obj as Class2  //  Will return NULL if the casting cannot be made

0

as 不能用于值类型(非可空类型)。

对于引用类型...

expression as type

真的和

expression is type ? (type) expression : (type) null

除了expression只被评估一次之外。

为了向比尔·克林顿致敬,在“expression is type”中的“is”我指的是“is”。

基本上,正如其他答案所示,这意味着当强制转换失败时,as返回null。但是,当强制转换成功但类型错误时,它也会返回null。

这里有一个有点傻的例子:

uint? u = 52;
int? i = (int?) u;   // 'i' is now 52

但是

uint? u = 52;
object d = u;
int? i = d as int?;

i的值是多少?52?不对,它是null。

为什么有个对象在那里?事实证明,当我用“is”解释“as”时,我撒了谎。

观察:

uint? u = 52;
int? i = (u is int?) ? (int?) u : (int?) null;

'i'现在是null

uint? u = 52;
int? i = u as int?;

糟糕。编译器错误。看来这两个语句并不完全相同。


2
简而言之:is就是is,as也是as,is还是is。 - Eric Lippert
不仅如此,我还得写使用“?”的C#代码,就像Lisp使用括号一样。 :-) - Justin

0
如果使用 "as" 关键字,您将永远不会遇到转换异常。 如果您尝试进行无效转换,则转换的结果将为 null。
隐式/显式转换可在具有继承/实现关系的类/接口之间使用,否则将导致编译错误。 请参见示例:
public class A {}
public class B {}
...
A a = new A();
//B b = (B)a;  //compile error:Cannot implicitly convert type 'A' to 'B'

另一种隐式/显式转换的情况是类A和B之间没有关系,但你自己编写了隐式/显式运算符。


0

此外,as 只能用于引用类型。这实际上是相当合理的,因为如果转换失败,它会返回 false,而这不是值类型的可能值。

因此,对于值类型,必须使用普通类型转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接