C# 具有内部基的接口继承

C# 具有内部基的接口继承,c#,inheritance,interface,C#,Inheritance,Interface,我想知道是否有办法实现以下目标: 在我的项目中,我定义了一个接口,比如IFruit。此接口有一个公共方法GetName()。我还声明了一个接口IApple,它实现了IFruit并公开了一些其他方法,比如GetAppleType()或其他什么。还有更多的水果,比如伊巴纳纳、艾氏莓等等 现在在外部,我只希望能够使用实际的水果实现,而不是IFruit本身。但是我不能将IFruit接口声明为private或internal,因为继承的接口会说“无法实现,因为基类不易访问” 我知道这在抽象实现中是可能的,

我想知道是否有办法实现以下目标:

在我的项目中,我定义了一个接口,比如IFruit。此接口有一个公共方法GetName()。我还声明了一个接口IApple,它实现了IFruit并公开了一些其他方法,比如GetAppleType()或其他什么。还有更多的水果,比如伊巴纳纳、艾氏莓等等

现在在外部,我只希望能够使用实际的水果实现,而不是IFruit本身。但是我不能将IFruit接口声明为private或internal,因为继承的接口会说“无法实现,因为基类不易访问”

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

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


内部接口IFruit
{
公共字符串GetName();
}

公共接口应用:IFruit { 公共十进制GetDiameter(); }

公共接口IBanana:IFruit { 公共十进制getLength(); }


但由于基本接口不易访问,因此无法编译。

如果您的代码中有什么内容(假设我正确理解您的状态),请执行以下操作:

public class WaterMellon : IFruit, IVegetables...
{
}
如果你想让你的框架使用者只访问一个
IFruit
的方法,那么我就没有其他已知的方法了

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

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

您确实不可能完成您正在尝试的操作,但是您可以使用带有
[过时]
属性的IFruit界面,并通过消息说明原因

在你的IBanana上,IApple。。。接口,禁止显示过时警告

[Obsolete]
public interface IFruit {
    ...
}

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

一种确保不会意外发生这种情况的方法是将
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());
    }
}
然后:

如果名称可能随时间而改变,您还可以轻松地将其扩展为对调整的对象懒洋洋地调用
GetName



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

如果你不想使用它,接口的意义是什么?每个fruit接口将共享一组他们都需要的通用方法。在内部,我的项目使用接口。我只是希望外部世界不能实施它。此解决方案的某些部分加载了MEF。指定常用方法的“基本接口”不是实际加载的接口类型。因此,当一个程序员同事在实现IFruit时犯了错误,他的工作将无法加载。我想避免这个错误。如果你真的想这样做,那么我觉得你需要包装纸。。。。只公开那些应该公开的东西,然后当你在内部使用它们时,你就用实现内部接口的内部包装器来包装它们。(是的,这意味着您必须将
GetName();
添加到每个特定的水果中,并为每个水果单独包装……但从外部API的角度来看,这是唯一干净的方法……。这不是一个坏主意。如果签入策略阻止签入带有警告的代码,那么这确实会阻止使用接口。谢谢我想这是可行的,但它并没有真正帮助代码的可读性。我会选择另一个我更喜欢的解决方案,但是我把这个方案投了更高的票给其他人看。谢谢。是的,但这是我能想到的使之不可能的唯一方法(当然,忽略恶意代码)。
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());