具有内部基的接口继承

本文关键字:接口 继承 内部 | 更新日期: 2023-09-27 18:35:47

我想知道是否有办法完成以下任务:

在我的项目中,我定义了一个接口,比如 IFruit。此接口有一个公共方法 GetName()。我还声明了一个接口 IApple,它实现了 IFruit 并公开了一些其他方法,如 GetAppleType() 或其他方法。还有更多的水果,比如IBanana,ICherry,随便什么。

现在在外面,我只想使用实际的水果实现,而不是IFruit本身。但是我不能将 IFruit 接口声明为私有或内部接口,因为继承的接口会说"无法实现,因为基类不太容易访问"。

我知道这可以通过抽象实现来实现,但在这种情况下这不是一个选择:我真的需要使用接口。有这样的选择吗?

更新我想我的例子需要一些澄清:)我使用 MEF 来加载接口实现。加载的集合基于 IApple、IBanana、ICherry 等。但是 IFruit 本身是无用的,我不能只使用基于该接口的类。所以我正在寻找一种方法来防止其他开发人员仅实现 IFruit,认为他们的类将被加载(它不会)。所以基本上,它归结为:


internal interface IFruit
{
  public string GetName();
}

public interface IApple : IFruit { public decimal GetDiameter(); }

public interface IBanana : IFruit { public decimal GetLenght(); }

But that won't compile due to the less accessible base interface.

具有内部基的接口继承

One way that you can guarantee this doesn't happen unintentionally is to make IFruit internal to your assembly and then use some adaptor to wrap the type appropriately:

public interface IApple { string GetName(); }
public interface IBanana { string GetName(); }
internal interface IFruit { string GetName(); }
class FruitAdaptor: IFruit
{
    public FruitAdaptor(string name) { this.name = name; }
    private string name;
    public string GetName() { return name; }
}
// convenience methods for fruit:
static class IFruitExtensions
{
    public static IFruit AsFruit(this IBanana banana)
    {
        return new FruitAdaptor(banana.GetName());
    }
    public static IFruit AsFruit(this IApple apple)
    {
        return new FruitAdaptor(apple.GetName());
    }
}

然后:

MethodThatNeedsFruit(banana.AsFruit());

如果名称可能随时间而更改,您还可以轻松地将其扩展到在改编对象上懒惰地调用GetName


另一种选择可能是进行仅 DEBUG 检查,该检查确实加载了所有IFruit实现者,然后如果其中一个实际上没有实现 IBanana/IApple ,则引发异常。由于听起来这些类是供公司内部使用的,因此这应该可以防止任何人意外实现错误的东西。

实际上不可能做你正在尝试的事情,但你可以让人们使用带有[Obsolete]属性的 IFruit 接口,并用消息说明原因。

在你的IBanana,IApple,...接口,禁用过时警告的出现。

[Obsolete]
public interface IFruit {
    ...
}
#pragma warning disable 612
public interface IBanana : IFruit {
    ...
}
#pragma warning restore 612

如果你的代码中有某种方法(假设我正确理解了你的状态),像这样:

public class WaterMellon : IFruit, IVegetables...
{
}

并且您希望能够使框架的消费者只能访问IFruit的方法,对我来说没有其他已知的方法,然后简单地投射。

IFruit fruit = new WaterMelon();
fruit. //CAN ACCESS ONLY TO FRUIT IMPLEMNTATION AVAILABLE IN WATERMELON

如果这不是您要要求的,请澄清。