7

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

在我的项目中,我定义了一个接口,比如说 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(); }

但是由于基础接口的可访问性较低,这将无法编译。

4

3 回答 3

6

您可以保证这不会无意中发生的一种方法是制作IFruit internal您的程序集,然后使用一些适配器适当地包装类型:

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如果名称会随着时间而改变,您也可以轻松地将其扩展为懒惰地调用适应的对象。


另一种选择可能是进行仅调试检查以加载所有实现,然后如果其中一个实际上没有实现/IFruit则抛出异常。因为听起来这些类是供公司内部使用的,所以这应该可以防止任何人意外实现错误的东西。IBananaIApple

于 2012-05-29T09:32:47.383 回答
2

确实不可能做你正在尝试的事情,但你可以使用带有[Obsolete]属性的 IFruit 界面来阻止人们,并通过消息说明原因。

在您的 Ibanana、IApple、... 接口上,禁用过时警告的出现。

[Obsolete]
public interface IFruit {
    ...
}

#pragma warning disable 612
public interface IBanana : IFruit {
    ...
}
#pragma warning restore 612
于 2012-05-29T09:18:25.043 回答
0

如果您的代码中有某种方式(假设我正确理解了您的状态),则如下所示:

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

并且您希望能够让您的框架的使用者访问的方法IFruit,我没有其他已知的方法,然后简单地进行转换。

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

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

于 2012-05-29T08:46:37.273 回答