如何实现内部接口的成员

时间:2009-08-03 09:23:12

标签: c# interface internal

我一直在重构我目前正在进行的项目的代码库,以便在程序集范围之外无用的类/接口应声明为内部(而不是公共)。但是我遇到了以下代码的问题:

internal interface IFirstInterface
{
    ...
}

internal interface ISecondInterface
{
    IFirstInterface First{ get; }
    ...
}

public class Implementer : ISecondInterface
{
    public IFirstInterface First {get; private set;}
    ...
}

我的问题:

  1. 为什么内部接口的成员必须公开实施?如果在内部类上实现接口,那么实现的成员不应该是内部的吗?这不是一个大问题,因为接口成员无论如何都不会公开访问,因为类是内部的。这似乎与直觉相反。

  2. 主要问题在于上面的场景,因为我不能为IFirstInterface提供公共getter,因为它据称是一个内部接口,即我从编译器得到以下错误:

  3.   

    可访问性不一致:属性   类型'IFirstInterface'更少   比财产更方便   'Implementer.First'

    有什么方法吗?

    注意:我意识到这个重构练习可能没什么价值,但我认为这将是一个很好的方式让我更深入地了解内部修饰符的含义。

3 个答案:

答案 0 :(得分:48)

请注意 - 您实际提供的代码编译,因为Implementer是一个内部类。当Implementer公开时会出现问题。

这样做的方法是使用显式接口实现:

public class Implementer : ISecondInferface
{
    private IFirstInterface first;
    IFirstInterface ISecondInterface.First { get { return first; } }
}

你不能拥有setter,因为你明确地实现了没有定义setter的接口。你可以做另一种选择:

public class Implementer : ISecondInterface
{
    internal IFirstInterface First { get; private set; }
    IFirstInterface ISecondInterface.First { get { return First; } }
}

不幸的是,内部接口有公共成员 - 它确实使这样的事情变得复杂。公共接口有一个内部成员(实现者或声明者的内部成员是什么?)会很奇怪,但对于内部接口来说,它更有意义。

答案 1 :(得分:11)

  

为什么内部接口的成员必须公开实施?

定义接口时,不要为成员定义访问级别,因为所有接口成员都是public。即使这样的界面是internal,成员仍被视为public。当您对这样的成员进行隐式实现时,签名必须匹配,因此它必须是public

关于暴露getter,我建议改为创建一个显式接口的实现,并创建一个internal属性来公开该值:

internal IFirstInterface First { get; private set; }

IFirstInterface ISecondInterface.First
{
    get { return this.First; }
}

答案 2 :(得分:7)

我知道这篇文章已有几年了但我认为值得注意的是你可以在公共类上实现内部接口,请参阅以下链接:

http://forums.create.msdn.com/forums/p/29808/167820.aspx
http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx

来自第一个链接的示例:


internal interface ISecretInterface
{
    string Property1 { get; }
}

public class PublicClass : ISecretInterface
{
    // class property
    public string Property1
    {
        get { return "Foo"; }
    }

    // interface property
    string ISecretInterface.Property1
    {
        get { return "Secret"; }
    }
}