2 回答
TA贡献1851条经验 获得超4个赞
您需要区分编译时类型(例如确定调用方法的哪个重载的那些)和运行时类型(例如反射使用的那些)。无论您对特定对象1 进行何种扭曲(将其转换为基类型等)都不会更改对象的运行时类型。
所以,仅仅因为你传递t
给Print
它要求一个TrxBase
,它不会改变 t
成TrxBase
。
如果在 inside 中Print
测试并确定它是 a Trx
,则将其强制转换回该类型(隐藏在模式匹配语法中)并开始将其视为真正的类型(当然,尽管,它可能是一种更源自Trx
.
额外阅读:埃里克·利珀特的代表和身份
1如果您了解引用更改转换为您提供了一个新对象。这在上面的奖励阅读中也有进一步的解释。
TA贡献1866条经验 获得超5个赞
这就是 C# 的工作方式,当您将派生类型对象传递给具有基类型对象参数的方法时,编译器只需获取此派生对象并将其解释为基类。
在您的情况下,您将派生 ( Trx
) 对象传递给带有TrxBase
参数的方法。因此,现在在 的范围内Print(TrxBase trx)
,trx
将被视为TrxBase
, 但随后您将使用模式匹配来确定这是否trx
可以表示为更派生的Trx
对象类型,在您的情况下是正确的,因此可以打印prop 3
。
可以将派生类型转换为更多基类型,但另一种方式将导致InvalidCastException
来自 CLR。因为如果您考虑一下 - 假设您分配类型为的新对象TrxBase
,CLR 分配器将在堆(或堆栈,如果值类型)上分配此类对象,并具有该对象具有的所有所需属性。现在,如果您从 CLR 请求将此特定对象转换为更具体的对象,您最终会请求将此特定内存布局更改为 CLR 不支持的另一个(从您的特定对象添加字段、属性等)。
- 2 回答
- 0 关注
- 269 浏览
添加回答
举报