【问题标题】:How do I implement members of internal interfaces如何实现内部接口的成员
【发布时间】:2010-11-16 07:45:07
【问题描述】:

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

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 修饰符含义的好方法。

【问题讨论】:

  • 如果可以选择,您可以通过使用抽象基类来绕过接口方法公开的限制。

标签: c# interface internal


【解决方案1】:

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

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

【讨论】:

  • 啊,正确。我将编辑我的问题,以免读者感到困惑。谢谢!
【解决方案2】:

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

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

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

internal IFirstInterface First { get; private set; }

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

【讨论】:

    【解决方案3】:

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

    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 年的答案与 2009 年的两个答案有何不同?
    • 老实说,我不知道,我知道为什么我会添加它,尽管我确实记得这样做过。它没有添加任何东西,我一直试图通过查看修订历史来弄清楚它是否有线索但仍然没有。也许我度过了愚蠢的一天。
    • 由于某种原因,这个答案比之前的答案更容易让我理解,因为答案开头的解释解决了我的情况并与我在谷歌上搜索的内容相匹配。因此,感谢您明确指出公共类可以以易于使用的方式实现内部接口;-)。
    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多