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

.NET Framework中同基类子类对象转换问题求助

同基类子类对象转换问题解答

核心结论

两个继承自同一基类的子类对象不能直接强制转换,因为它们是完全独立的类型实例。编译期允许这种写法是因为编译器只检查类型的继承层级(Child1和Child2都能转成Base,Base理论上可以转成任何子类),但运行时CLR会验证对象的实际类型,发现child1是Child1实例,无法转成Child2,因此抛出InvalidCastException。

你的代码问题分析

你代码里用new关键字隐藏了基类的print_me方法,这不是真正的多态重写。即使把Child1转成Base,调用print_me时还是会执行基类的方法,而非Child1的实现。正确的做法是把基类方法设为virtual,子类用override重写。

解决方案

方案1:手动属性映射(最基础)

如果两个子类有需要共享的属性,手动创建目标类的实例,将源对象的属性值复制过去。示例:

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        Child1 child1 = new Child1 { Name = "Test", Age = 20 };
        child1.PrintMe();
        
        // 手动映射属性创建Child2实例
        Child2 child2 = new Child2 
        { 
            Name = child1.Name, 
            Age = child1.Age 
        };
        child2.PrintMe();
    }

    private class Base
    {
        public string Name { get; set; }
        public int Age { get; set; }
        
        // 改为虚方法支持多态
        public virtual void PrintMe()
        {
            Console.WriteLine($"I am Base, Name: {Name}, Age: {Age}");
        }
    };

    private class Child1 : Base
    {
        // 重写基类方法
        public override void PrintMe()
        {
            Console.WriteLine($"I am Child1, Name: {Name}, Age: {Age}");
        }
    };

    private class Child2 : Base
    {
        public override void PrintMe()
        {
            Console.WriteLine($"I am Child2, Name: {Name}, Age: {Age}");
        }
    };
}

方案2:使用对象映射工具(简化重复工作)

如果子类属性较多,可以用AutoMapper这类工具自动映射。先安装NuGet包AutoMapper,然后配置映射:

using System;
using AutoMapper;

public class Program
{
    public static void Main()
    {
        // 配置映射
        var config = new MapperConfiguration(cfg => cfg.CreateMap<Child1, Child2>());
        var mapper = config.CreateMapper();

        Child1 child1 = new Child1 { Name = "Test", Age = 20 };
        child1.PrintMe();
        
        // 自动映射
        Child2 child2 = mapper.Map<Child2>(child1);
        child2.PrintMe();
    }

    // 基类和子类定义同方案1
    private class Base { /* ... */ }
    private class Child1 : Base { /* ... */ }
    private class Child2 : Base { /* ... */ }
}

方案3:如果只是想执行子类方法(无需转换)

如果你的需求不是转换对象,而是想调用Child2的方法,直接实例化Child2即可,不需要转换Child1对象:

Child2 child2 = new Child2();
child2.PrintMe();

内容的提问来源于stack exchange,提问作者NANDHA KUMAR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:33:29