C# 中as运算符的用法问题

【代码——】

img

【报错——】
CS0039:Cannot convert type 'Wen.Peach' to 'Wen.Apple' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

【问题——】
不是说:运用as运算符,就算转换失败,也是返回null值吗?
为什么这段代码不可以,会直接报错?

(ps:但如果把【Peach p = new Peach ();】改为【Object p = new Peach ();】就会正常返回null值)

这是为什么?谢谢。

该回答引用ChatGPT4与博主@晓码自在合作编写:

你的疑问很好,as 运算符用于尝试进行类型转换,即使转换失败也会返回 null 而不报错。

但是在你的代码中,as 运算符尝试将 Wen.Peach 类型转换为 Wen.Apple 类型,这两个类型没有继承关系,所以转换失败并报错。

as 运算符可以在以下情况下成功转换并返回目标类型:

  1. 转换源类型和目标类型有继承关系
  2. 转换源类型可以向上转型为目标类型(如派生类到基类)
  3. 转换源类型实现了目标类型的接口

在你的例子中,Wen.Peach 和 Wen.Apple 是两个独立的类型,不满足上述任意一条,所以转换失败并报 CS0039 错误。

当你将 Wen.Peach 改为 Object 类型后,代码可以成功运行,因为:

  1. Wen.Peach 继承自 Object,满足可以向上转型为 Object
  2. 所以 as 运算符尝试将 Wen.Peach 转换为 Object 成功,并返回 Object 类型
  3. 然后判断对象 a 是否为 null,本例返回 null

所以,as 运算符尝试进行类型转换,如果满足转换条件会返回目标类型,否则返回 null。但如果类型之间根本不满足任何转换条件,则会报类型转换错误,而不会返回 null。

因为Peach和Apple根本没有继承关系,所以编译期间就给你检查出来报错。

c#是强类型的编程语言,你的类之间是否有继承关系,这个在编译阶段就能确定,不用等运行起来
你让两个完全没有继承关系的类相互转换,直接编译报错
至于运行期间p会不会是null,这编译器就没法确定了
如果你用强制转换,你把null强制转换成一个类型肯定要运行期间抛异常,而用as则可以避免这个问题