什么是私人界面?

Ric*_*dOD 46 c#

前一段时间,面试官在接受采访时问我"你会用什么私人接口?".

我问他是否意味着他回答否的隐式与显式接口实现之间的区别.

所以我想知道:

  1. 他是什么意思?
  2. 您将使用私有界面?

Shu*_*oUk 34

接口可以在另一个类中是私有的

public class MyClass
{
    private interface IFoo
    {
        int MyProp { get; }
    }

    private class Foo : IFoo
    {
        public int MyProp { get; set; }
    }

    public static void Main(string[] args)
    {
        IFoo foo = new Foo();
        return foo.MyProp;
    }
}
Run Code Online (Sandbox Code Playgroud)

在实用程序方面,它简单地隐藏在其他代码中,即使在同一个程序集中,也存在所述接口存在.在我看来,这个用途并不是非常高.

显式接口实现是一个不同的问题,有一些非常有用的情况(特别是在使用泛型和较旧的非泛型接口时)但我不会将其称为"私有接口",并且不会说该术语通常以这种方式使用.

将这两种技术结合使用,您可以:

public class MyClass
{
    private interface IFoo
    {
        int MyProp { get; }
    }

    public class Foo : IFoo
    {
        int IFoo.MyProp { get; set; }
    }

    public static void Main(string[] args)
    {
        IFoo foo = new Foo();
        return foo.MyProp;
    }
}

public class HiddenFromMe
{
    public static void Main(string[] args)
    {
        MyClass.Foo foo = new MyClass.Foo();
        return foo.MyProp; // fails to compile
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许您以某种方式公开嵌套类,同时允许父类调用外部世界不能的方法.这是一个潜在有用的案例,但我不希望经常使用.当然,在面试中使用它是因为他们已经看到它并且虽然它是"有趣的"

  • 虽然这是真的,但这不是接口最无用的用法之一吗?我不明白为什么你会用这种结构. (6认同)
  • 对不起John你错了"显式接口实现并不一定意味着实现接口的方法是私有的"在我的回答中特别阅读链接文档:"显式接口成员实现包含的编译时错误访问修饰符"和"因为显式接口成员实现永远不能通过方法调用或属性访问中的完全限定名来访问,所以它们在某种意义上是私有的.但是,由于它们可以通过接口实例访问,因此它们位于感觉也是公开的." (3认同)
  • 我在关于实用程序(或缺少实用程序)的问题中添加了评论我认为面试官可能一直在使用错误的术语来明确界面实现,但这是猜测 (2认同)
  • @RichardOD:不完全是==.显式接口实现并不一定意味着实现接口的方法是私有的.但是,在私有接口继承中,它们具体是.显式实现可以使用不同名称的公共方法(EG,"Close"用于实现IDisposable.Dispose),具有相同名称的公共成员或私有成员来完成.后一种情况是真正创建私有接口继承 - 您不能使用没有强制转换到接口的接口成员. (2认同)

Mar*_*son 10

这个链接.

专用接口继承

从历史上看,语言允许私有继承.在C++中,您可以从类型继承而不与该类型进行多态兼容.这只是重用实现的便捷方式.在CTS中,您无法进行私有实现继承.但您可以使用私有接口继承.

私有接口继承实际上只是一种从类型的公共API隐藏方法的方法.它们被编译为私有方法,但实际上可以通过类型的接口映射访问.换句话说,它们只能通过类型化的引用来调用,作为定义方法的接口.一个例子将使这更容易理解:

class PrivateImplementer : IFoo
{
   void IFoo.Foo()
   {
       Console.WriteLine("PrivateImplementer::IFoo.Foo");
   }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,PrivateImplementer公知已实施IFoo.因此,可以将实例多态地视为实例IFoo.但除非你把它视为一个,否则你实际上不能称它为Foo IFoo.此代码演示了这一点:

PrivateImplementer p = new PrivateImplementer();
p.Foo(); // This line will fail to compile
IFoo f = p;
f.Foo();
Run Code Online (Sandbox Code Playgroud)

您可以选择接口的各个方法来私下实现.例如,如果PrivateImplementer实现IFooBar,它可能选择私下实现Foo,但Bar公开使用普通语法.

实际上,您使用私有实现的常见情况并不多.该System.Collections.Generic库使用此方法秘密实现所有遗留的System.Collections弱类型接口.这使得向后兼容性"正常工作",例如将一个实例传递List<T>给期望一个IList将正常工作的方法.在这个具体的例子中,混乱新类型的API会很遗憾(弱类型互操作性需要很多方法).

"不,"如果他想找出你所知道的,那就是一个非常糟糕的答案.听起来像是只想表明他们知道多少的人.

  • 这是明确的界面实现,面试官说这不是他的意思. (6认同)
  • 没错,答案可能只是你的面试官是个家伙. (6认同)
  • 这只是一个可怕的,可怕的问题."你什么时候会使用这种模糊的技术,你几乎肯定没有遇到过?" 正确答案:几乎从不.答案不正确:我不知道,我从未使用过它.我称之为恶作剧. (4认同)
  • 嗨Mark,我看到那个网页也不是和显式接口实现一样吗? (2认同)