是否有可能解决接口继承中使用的传递闭包?

时间:2015-12-01 13:43:10

标签: c# interface multiple-inheritance

使用界面继承,我希望在终端界面/类中有来自所有祖先的所有项目,我也希望有一个基本接口,用于所有派生接口/对象(继承树根),用于常规对象处理,如Process(IBase b) 。所以,例如,而不是:

public interface IBase 
{
    Guid Id {get;} 
    void SwitchOn();
}

public interface IPart1 : IBase {void DoPart1Specific();}
public interface IPart2 : IBase {void DoPart2Specific();}
public interface ICompound1 : IPart1, IPart2 {}

public class Compound : ICompound1
{
    public Guid Id => Guid.Empty;        // IBase
    public void SwitchOn() {}            // IBase
    public void DoPart1Specific() {}     // IPart1
    public void DoPart2Specific() {}     // IPart2
}

我想有这样的东西(使用伪显式接口实现符号当然不会在这里工作):

public class Compound : ICompound1
{
    Guid Part1.Id => Guid.Empty;         // ICompound1.IPart1
    void Part1.SwitchOn() {}             // ICompound1.IPart1
    void DoPart1Specific() {}            // ICompound1.IPart1

    Guid Part2.Id => Guid.Empty;         // ICompound1.IPart2
    void Part2.SwitchOn() {}             // ICompound1.IPart2
    void DoPart2Specific() {}            // ICompound1.IPart2
}

我能够弄清楚的只是不那么好和部分解决方案是复制每个接口定义中的所有常见内容,这些内容过于冗长且容易出错(在这种情况下,显式实现有效并且让& #39; s说Compound类成员不能公开)并没有关系,但没有可用的基本接口)o:

public interface IPart1Ex
{
    Guid Id {get;} 
    void SwitchOn();
    void DoPart1Specific();
}

public interface IPart2Ex
{
    Guid Id {get;} 
    void SwitchOn();
    void DoPart2Specific();
}

public interface ICompound1Ex : IPart1Ex, IPart2Ex {}

public class CompoundEx : ICompound1Ex
{
    Guid IPart1Ex.Id => Guid.Empty;
    void IPart1Ex.SwitchOn() {}
    void IPart1Ex.DoPart1Specific() {}

    Guid IPart2Ex.Id => Guid.Empty;
    void IPart2Ex.SwitchOn() {}
    void IPart2Ex.DoPart2Specific() {}
}

2 个答案:

答案 0 :(得分:2)

看起来你根本不想继承接口,而是使用合成。您的Compound类需要包含Part1的实例和Part2的实例。这会产生类似的结果:

public interface IPart {
    Guid Id { get; }
    void SwitchOn();
    void Execute();
}

public class Compound
{
    private readonly IPart _part1;
    private readonly IPart _part2;

    public Compound(IPart part1, IPart part2)
    {
        _part1 = part1;
        _part2 = part2;
    }

    public Guid Part1Id { get { return _part1.Id; } }
    public void Part1SwitchOn() { _part1.SwitchOn(); }
    public void DoPart1Specific() { _part1.Execute(); }

    public Guid Part2Id { get { return _part2.Id; } }
    public void Part2SwitchOn() { _part2.SwitchOn(); }
    public void DoPart2Specific() { _part2.Execute(); }
}

或者更简单的课程就是:

public class Compound
{
    public Compound(IPart part1, IPart part2)
    {
        Part1 = part1;
        Part2 = part2;
    }

    public IPart Part1 { get; private set; }
    public IPart Part2 { get; private set; }
}

然后使用以下命令在调用代码中访问它们:

var compound = MyMethodWhichCreatesCompound();
var id1 = compound.Part1.Id;
compound.Part2.Execute();
//etc

答案 1 :(得分:0)

我认为在接口成员定义上使用new关键字可以帮助您:

public interface IBase 
{
    Guid Id {get;} 
    void SwitchOn();
}

public interface IPart1 : IBase
{
    new Guid Id {get;}
    new void SwitchOn();
    void DoPart1Specific();
}

public interface IPart2 : IBase
{
    new Guid Id {get;}
    new void SwitchOn();
    void DoPart2Specific();
}