You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中基类与派生类三类实例化场景的区别,重点解析obj1与obj2的差异

C# 三种基类/派生类实例化方式的差异

首先明确核心规则:C# 中每个对象都有两个关键类型:声明类型(变量定义时标注的类型,编译期确定)和实际实例类型(new 关键字后跟随的类型,运行时确定),二者的差异直接决定了成员访问权限和多态行为。

你给出的示例代码里三个实例的区别如下:

1. Shape obj1 = new Shape();

  • 声明类型:Shape,实际实例类型:Shape
  • 属于最常规的同类型实例化,你可以通过 obj1 直接访问 Shape 类中定义的所有成员:Property1、Property2,无法访问 Rectangle 类的扩展成员。
  • 运行时实际内存中就是 Shape 的实例,不包含任何 Rectangle 类的扩展属性和方法。

2. Shape obj2 = new Rectangle();

  • 声明类型:Shape,实际实例类型:Rectangle
  • 这是典型的向上转型,是 C# 多态的基础用法。运行时内存中创建的是完整的 Rectangle 实例,包含 Shape 的所有成员,也包含 Rectangle 自己定义的 Property3。
  • 受编译期的声明类型限制,你直接通过 obj2 只能访问 Shape 类定义的 Property1、Property2,直接写 obj2.Property3 会触发编译错误。如果要访问派生类成员,需要手动做向下转型:
    Rectangle rect = (Rectangle)obj2; // 转型不会报错,因为实际实例就是Rectangle
    Console.WriteLine(rect.Property3); // 可以正常访问
    

obj1 和 obj2 的核心差异

二者的声明类型都是 Shape,所以编译期允许访问的成员完全一致,但运行时的行为有本质区别:

  • 如果你尝试把 obj1 强转为 Rectangle,运行时会抛出 InvalidCastException 异常,因为 obj1 的实际实例就是 Shape,不属于 Rectangle 的子类实例
  • 如果 Shape 类中定义了虚方法,且 Rectangle 类做了重写,调用同一个方法时二者的执行逻辑完全不同:obj1 会执行 Shape 类的实现,obj2 会执行 Rectangle 类重写后的实现,这就是多态的核心表现。

3. Rectangle obj3 = new Rectangle();

  • 声明类型:Rectangle,实际实例类型:Rectangle
  • 实例类型和声明类型完全匹配,你可以直接访问所有继承自 Shape 的成员(Property1、Property2),也可以直接访问 Rectangle 自己定义的 Property3,不需要任何转型操作。

内容的提问来源于stack exchange,提问作者Amin Zahedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:36:00