【问题标题】:Inheriting abstract classes with abstract properties继承具有抽象属性的抽象类
【发布时间】:2013-05-16 21:17:53
【问题描述】:

我有具有抽象属性的基类。我希望所有继承类都覆盖抽象属性。示例:

public class Person
{
    public string Name{get;set;}
    public string LastName{get;set;}
}

public class Employee : Person
{
    public string WorkPhone{get;set;}
}

public abstract class MyBase
{
    public abstract Person Someone {get;set;}
}

public class TestClass : MyBase
{
    public override Employee Someone{get;set;} //this is not working
}

基类具有 Person 类型的 Some 属性。我正在覆盖我的TestClass 上的Someone 属性。现在我想使用Employee 类型而不是Person。我的Employee 类继承自Person。我无法让它工作。我应该怎么做才能避免这个问题?

帮助表示赞赏!

【问题讨论】:

标签: c# overriding abstract-class type-inference abstract-data-type


【解决方案1】:

问题是您可以将 Employee 分配给 Person 实例,但您不能也将 Person 分配给 Employee 实例。因此,您的二传手会中断。您要么需要摆脱 setter,要么使用私有支持实例和一些强制转换(我不推荐),如下所示:

public class TestClass : MyBase
{
    private Employee _employee;

    public Person Someone
    {
        get
        {
            return _employee;
        }
        set
        {
            if(!(value is Employee)) throw new ArgumentException();
            _employee = value as Employee;
        }
}

【讨论】:

  • 感谢您的解释!
  • 我最终也实现了这种方法,但我不喜欢它。鉴于我不能放弃二传手,那你有什么建议?还是 OP 和我自己使用这种模式错了?
【解决方案2】:

如果您希望派生类使用 ethier EmployeePerson,您可以使用 Generics

类似:

public class Person
{
    public string Name { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person
{
    public string WorkPhone { get; set; }
}

public abstract class MyBase<T> where T : Person
{
    public abstract T Someone { get; set; }
}

public class TestClass : MyBase<Employee>
{
    public override Employee Someone { get; set; } 
}

public class TestClass2 : MyBase<Person>
{
    public override Person Someone { get; set; }
}

【讨论】:

    【解决方案3】:

    这是一种返回类型协变的形式,不幸的是,在 C# 中是不允许的。

    查看 Eric Lippert 的回答 here

    【讨论】:

      【解决方案4】:

      简而言之:每个Employee 对象都是一个Person 对象。但并不是每个Person 对象都是Employee 对象。

      这就是编译器抱怨的原因,因为您希望它在某个地方将Employee 对象视为Person 对象明确需要Person - 它可以是任何派生自人包括 Employee不具体 Employee

      注意:@sa_ddam213 在她/他的回答中提供了一个解决方案,如果您确实需要明确这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-23
        • 1970-01-01
        • 2013-04-18
        • 2021-05-03
        • 1970-01-01
        • 2019-01-09
        • 1970-01-01
        • 2021-10-24
        相关资源
        最近更新 更多