25

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

internal interface IFirstInterface
{
    ...
}

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

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

我的问题:

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

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

可访问性不一致:属性类型“IFirstInterface”的可访问性低于属性“Implementer.First”

有没有办法解决?

注意:我意识到这个重构练习可能没有什么价值,但我认为这对我来说是更深入地理解 internal 修饰符含义的好方法。

4

3 回答 3

50

请注意 - 您实际提供的代码确实可以编译,因为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; } }
}

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

于 2009-08-03T09:26:49.913 回答
11

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

定义接口时,您不定义成员的访问级别,因为所有接口成员都是public. 即便是这样的界面internal,成员们也还是会考虑的public。当您对此类成员进行隐式实现时,签名必须匹配,因此它必须是public.

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

internal IFirstInterface First { get; private set; }

IFirstInterface ISecondInterface.First
{
    get { return this.First; }
}
于 2009-08-03T09:33:10.910 回答
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"; }
    }
}
于 2011-06-10T16:51:12.143 回答