具有逻辑性的C#特定假设实例中的多重继承替代

问题描述 投票:-4回答:1

假设有两个类具有相同的道具,在该道具中也有逻辑。

public class Manager
{
    private string _ssn { get; set; }

    [RegularExpression(@"\d{9}")]
    public string SSN
    {
        get
        {
            return _ssn;
        }
        set
        {
            if (!string.IsNullOrEmpty(value))
                _ssn = someLogicalMethod (value);
        }     
    }
}

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

    [RegularExpression(@"\d{9}")]
    public string SSN
    {
        get
        {
            return _ssn;
        }
        set
        {
            if (!string.IsNullOrEmpty(value))
                _ssn = someLogicalMethod(value);
        }     
    }
}

理想情况下,您将创建一个将继承的抽象基类(BaseSSN)。这一切都很好,但并不理想!原因是因为在C#中你只能从1个超类继承。这意味着如果你有一个Manager和Employee都有SSN,但是Manager和一个新类(CEO)有一个ManagerOf属性的情况,那么你必须创建一个实现BaseSSN类的新类,但它也是一个抽象类(BaseManagerOf),其中包含Managerof的逻辑。然后,经理和首席执行官将继承新课程。但是,如果有人是经理但是他们自己没有SSN,那么现在你必须创建另一个类。你需要拔出经理道具并把它放在一个超级,以将它与SSN类分开。

你知道我要去哪儿吗?根据每个类与其他类相似的道具数量,它可以创建N个变体。

所以我想做的就是简单

公共类管理器:BaseSSN,BaseManagerOf,X

X是什么的。您可以使用接口执行此操作,但接口不能包含逻辑。

我相信可能有一个平稳的策略可以解决这个问题,但无法解决这个问题。

编辑:

关于我的问题,似乎存在一些混淆:这是一个假设的问题。我知道经理是员工。简单的问题是我希望一个类实现2个摘要,而不能在C#中实现。但是,是否有一种策略可以让它以任何方式工作?

public class Manager : BaseManager
{
}

public abstract class BaseManager : BaseSSN
{

    private string _managerOf;
    public int ManagerOf
    { 
         get
         {
             return _managerOf;
         }
         set
         {
             if (!string.IsNullOrEmpty(value))
                 _managerOf = someLogicalMethod(value);
         }     
     }
}

public abstract class BaseSSN
{
    private string _ssn { get; set; }

    [RegularExpression(@"\d{9}")]
    public string SSN
    {
        get
        {
            return _ssn;
        }
        set
        {
            if (!string.IsNullOrEmpty(value))
                _ssn = someLogicalMethod(value);
        }     
    }
}

public class CEO : ManagerOf {}

现在它开始与CEO分道扬..我不想要首席执行官的SSN,只需要他管理的人。因此,我必须从继承SSN的ManagerOf类中拉出逻辑,并将其放在自己的类中。那么CEO就不会拥有SSN道具。但是,现在我不能在我的Manager类中同时拥有ManagerOf逻辑和SSN逻辑,而不会创建另一个类似于以下类的抽象...

public class ManagerOfAndSSN: SSN
{
    // repetitive manager logic here
}
c# object inheritance interface abstract
1个回答
0
投票

一个答案是使用接口和组合。实现该功能的“基础”类(例如ManagerOfSSN)实现了接口,然后将它们作为依赖项提供给需要它们的类:

public interface ISsn
{
    string Ssn { get; set; }
}
public interface IManagerOf
{
    List<Employee> Manages { get; set; }
}

public class Ssn : ISsn { ... }
public class ManagerOf : IManagerOf { ... }

现在,您可以将这些类注入组合它们的类中:

// here we are implementing the interfaces on the class
public class Employee : ISsn
{
    private ISsn _ssn;

    public Employee(ISsn ssn)
    {
        _ssn = ssn;
    }

    public string Ssn
    {
        get { return _ssn.Ssn; }
        set { _ssn.Ssn = value }
    }
}

public class Manager : ISsn, IManagerOf
{
    private ISsn _ssn;
    private IManagerOf _managerOf;

    public Employee(ISsn ssn, IManagerOf managerOf)
    {
        _ssn = ssn;
        _managerOf = managerOf;
    }

    public string Ssn
    {
        get { return _ssn.Ssn; }
        set { _ssn.Ssn = value }
    }

    public List<Employee> Manages
    {
        get { return _managerOf.Manages; }
        set { _managerOf.Manages = value; }
    }
}

或者,类的替代实现:

// here we're just going to expose each dependency as the interface
public class Employee : ISsn
{
    private ISsn _ssn;

    public Employee(ISsn ssn)
    {
        _ssn = ssn;
    }

    public ISsn Ssn => _ssn;
}

public class Manager2
{
    private ISsn _ssn;
    private IManagerOf _managerOf;

    public Employee(ISsn ssn, IManagerOf managerOf)
    {
        _ssn = ssn;
        _managerOf = managerOf;
    }

    public ISsn Ssn => _ssn;
    public IManagerOf ManagerOf => _managerOf;
}

这是一个相当简单的实现,在这种情况下,我选择简单地在支持该功能的每个类中实现接口。但是,如果您在属性周围有更复杂的逻辑,那么组合路由更有意义,因为您正在共享实现。它起初并不像多重继承那样“优雅”,但请参阅Why is Multiple Inheritance not allowed in Java or C#?,讨论为什么多重继承通常被认为会导致比它解决的更多麻烦。

© www.soinside.com 2019 - 2024. All rights reserved.