是否有可能绕过接口继承中使用的传递闭包



使用接口继承,我希望在终端接口/类中拥有所有祖先的全部项,并且我还希望为所有派生接口/对象(继承树根)拥有一个基接口,用于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
}

我能想到的唯一不太好的部分解决方案是在每个接口定义中复制所有常见的东西,这太冗长且容易出错(在这种情况下,显式实现有效,假设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() {}
}

您似乎根本不想从接口继承,而是使用组合。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

我认为在接口成员定义中使用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();
}

最新更新