【问题标题】:C# Inheritance & CastingC# 继承和强制转换
【发布时间】:2020-07-16 17:45:31
【问题描述】:

我得到以下异常:

InvalidCastException:无法将“员工”类型的对象转换为类型 '员工档案'。

我有以下代码:

    private class Employee
    {
        public string Name { get; private set; }

        public Employee()
        {
            this.Name = "employee";
        }

        public override string ToString()
        {
            return this.Name;
        }
    }

    private class EmployeeProfile : Employee
    {
        public string Profile { get; private set; }

        public EmployeeProfile() : base()
        {
            this.Profile = string.Format("{0}'s profile", this.Name);
        }

        public override string ToString()
        {
            return this.Profile;
        }
    }

    public void RunTest()
    {
        Employee emp = new Employee();
        EmployeeProfile prof = (EmployeeProfile)emp; // InvalidCastException here

        System.Console.WriteLine(emp);
        System.Console.WriteLine(prof);
    }

也许我的大脑已经烧毁了,但我认为你可以将一个子类型转换为它的基本类型?我在这里想念什么?也许这是一个假期...谢谢!

【问题讨论】:

    标签: c# inheritance


    【解决方案1】:

    可以将子类型转换为其基类型。但是您将基类型的实例强制转换为子类型。

    一个 EmployeeProfile 是一个雇员。不一定相反。

    所以这工作:

    EmployeeProfile prof = new EmployeeProfile();
    Employee emp = prof;
    

    但是,这个模型的设计很糟糕。员工档案不是一种特殊的员工,是吗?员工拥有个人资料更有意义。您在此处的构图模式之后。

    【讨论】:

    • 我在帖子中犯了一个小错误 - 请查看更新后的内容:EmployeeProfile prof = (EmployeeProfile)emp; // 这里是 InvalidCastException
    • @WeekendWarrior:没关系。您仍然不能将基类型的实例强制转换为派生类型。您可以向另一个方向投射。
    • cdhowie 所说的仍然有效,您仍在尝试将基本类型转换为子类型。
    • 组合模式很有意义。 EmployeeProfile 与 Employee 具有一对一的关系——它只包含其他属性。谢谢你的提示!
    • @WeekendWarrior:当然,没问题。
    【解决方案2】:

    所有答案都是正确的......只是提供一个简单的解释......

    class Employee
    
    class Female : Employee
    
    class Male: Employee
    

    仅仅因为你是Employee 并不能使你成为Female...

    【讨论】:

    • 这是一种很好的思考方式……这很有帮助。非常感谢。
    • 如果您有一个员工列表,并且男性和女性具有独特的属性,您将如何计算,例如,有多少女性生了孩子?或者有多少男性进行了输精管结扎术?大声笑试图在提到的类之后提出示例。我需要知道如何适当地转换为他们的类型以获得独特的属性。谢谢!
    【解决方案3】:

    也许我的大脑已经烧坏了,但我 以为您可以将子类型转换为其 基本类型?

    您正在尝试将基类型转换为其子类型。和你说的完全相反:

    Employee emp = new Employee();
    EmployeeProfile prof = emp;
    

    【讨论】:

      【解决方案4】:

      你走错了方向。在您的代码中,EmployeeProfile 是一种特殊类型的 Employee,而不是相反。因此,当您尝试反向转换时,编译器会说“Employee”不是从“EmployeeProfile”派生的

      【讨论】:

        【解决方案5】:

        您需要 EmployeeProfile 中的一个方法,该方法将 Employee 作为参数并创建一个 EmployeeProfile。

        EmployeeProfile enrichEmployee(Employee emp)
        {
           EmployeeProfile empprof = new EmployeeProfile();
           empprof.property1 = emp.property1;
           empprof.property2 = emp.property2;
           empprof.property3 = emp.property3;
        
           return empprof;
        }
        

        【讨论】:

        • 严格来说,您“需要”派生类中的一个方法,该方法从基类中分配所有属性,这并不完全正确。这是一种执行属性分配的冗长方法,而对象级分配将适用于所有可用的匹配属性。
        【解决方案6】:

        您需要使用像 Automapper 这样的库。该库可以填充对象的匹配属性:

        Mapper.Initialize(cfg => {
            cfg.CreateMap<EmployeeProfile,Employee>();
        });
        
        EmployeeProfile prof = Mapper.Map<EmployeeProfile>(emp);
        

        【讨论】:

        • 不适合我
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-21
        • 1970-01-01
        • 2011-11-17
        • 2011-01-05
        • 2010-11-30
        • 2012-02-04
        相关资源
        最近更新 更多