C#继承和转换

9
我得到了以下异常:
InvalidCastException:无法将类型为“Employee”的对象强制转换为类型“EmployeeProfile”。
我有以下代码:
    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);
    }

也许我的大脑已经烧坏了,但我认为你可以将子类型转换为其基础类型?我错过了什么吗?也许这是一个假期...谢谢!
6个回答

19

您可以将子类型转换为其基本类型。但是,您正在将基本类型的实例转换为子类型。

EmployeeProfile 是 Employee 的子类型。但不一定反之。

因此,这样做是可行的:

EmployeeProfile prof = new EmployeeProfile();
Employee emp = prof;
然而,这个模型的设计很糟糕。员工档案不是一种特殊类型的员工,对吧?让员工拥有一个档案更合理。在这里需要使用组合模式。

我在我的帖子中犯了一个小错误 - 请查看更新的代码:EmployeeProfile prof = (EmployeeProfile)emp; // 这里会抛出 InvalidCastException 异常。 - Steven Striga
@WeekendWarrior:这并不重要。你仍然不能将基类型的实例强制转换为派生类型。你可以尝试在另一个方向上进行强制转换。 - cdhowie
cdhowie所说的仍然成立,您仍在尝试将基本类型强制转换为子类型。 - DeusAduro
组合模式很有意义。EmployeeProfile与Employee之间存在一对一的关系 - 它只包含额外的属性。谢谢你的提示! - Steven Striga

18

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

class Employee

class Female : Employee

class Male: Employee

仅仅因为你是一个 Employee 并不意味着你是一个 Female...


1
这是一个很好的思考方式...这对我帮助很大。非常感谢。 - Steven Striga
如果你有一个员工列表,男性和女性有独特的属性,你该如何计算例如有多少女性生过孩子?或者有多少男性做过结扎手术?哈哈,试图根据提到的类别来举例。我需要知道如何适当地将它们转换为其类型以获取独特的属性。谢谢! - Alex

2
你需要使用像Automapper这样的库。这个库可以为一个对象填充匹配的属性:
Mapper.Initialize(cfg => {
    cfg.CreateMap<EmployeeProfile,Employee>();
});

EmployeeProfile prof = Mapper.Map<EmployeeProfile>(emp);

2

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

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

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

0
你需要在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;
}

并不是严格要求在派生类中“需要”一个方法来分配所有基类属性。这是一种冗长的方式来执行属性分配,而对象级别的分配将适用于所有可用的匹配属性。 - JasonInVegas

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接