关于c#:什么是私有接口?


What is a private interface?

不久前在一次.NET职位的面试中,面试官问我:"你会用一个私人界面做什么?".

我问他,他说的是隐式和显式接口实现之间的区别吗?他回答说不是。

所以我想知道:

  • 他的意思是什么?
  • 使用私有接口的目的是什么?

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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;
        }
    }

    就实用性而言,它只是对其他代码隐藏,即使是在同一个程序集中,也存在这样的接口。在我看来,这种方法的效用并不高。

    显式接口实现是另一回事,有一些非常有用的情况(尤其是在处理泛型和较旧的非泛型接口时),但我不会将其称为"私有接口",也不会说该术语通常以这种方式使用。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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
        }
    }

    这允许您以某种方式公开嵌套类,同时允许父类调用外部世界无法调用的方法。这是一个潜在的有用案例,但我不希望经常使用它。当然,它在面试中的使用有点像一个边界案例,面试官使用它是因为他们已经看过了,尽管它很有趣。


    从这个链接。

    Private Interface Inheritance

    Historically, languages have permitted private inheritance. In C++, you can inherit from a type without being polymorphically compatible with that type. It’s just a convenient way to reuse an implementation. In the CTS, you cannot do private implementation inheritance. But you can use private interface inheritance.

    Private interface inheritance is really just a way to hide methods from a type’s public API. They are compiled into private methods but are actually accessible through a type’s interface map. In other words, they can only be called through a reference typed as the interface on which the method is defined. An example will make this easier to understand:

    1
    2
    3
    4
    5
    6
    7
    class PrivateImplementer : IFoo
    {
       void IFoo.Foo()
       {
           Console.WriteLine("PrivateImplementer::IFoo.Foo");
       }
    }

    In this case, PrivateImplementer is publicly known to implement IFoo. Thus, an instance can be treated polymorphically as an instance of IFoo. But you cannot actually call Foo on it unless you do treat it as an IFoo. This code demonstrates this:

    1
    2
    3
    4
    PrivateImplementer p = new PrivateImplementer();
    p.Foo(); // This line will fail to compile
    IFoo f = p;
    f.Foo();

    You can select individual methods of an interface to implement privately. For instance, if PrivateImplementer implemented IFooBar, it might choose to implement Foo privately, but Bar publicly using the ordinary syntax.

    In practice, there aren’t many common cases where you would use private implementation. The System.Collections.Generic library uses this approach to secretly implement all of the legacy System.Collections weakly typed interfaces. This makes backwards compatibility"just work," for example passing an instance of List to a method that expects an IList will work just fine. In this specific example, cluttering the new type APIs would have been a pity (there are quite a few methods necessary for the weakly typed interoperability).

    "不,"如果他想知道你所知道的,那是个很糟糕的回答。听起来像是一个只想展示他们知道多少的人。


    Shuggycouk给出了很好的回答,但有这样的评论。

    This is a potentially useful case but is not something I would wish to use very often. Certainly it's use in an interview smacks of being a boundary case the interviewer is using because they've seen it and though it was 'interesting'

    我必须说,这绝对不是只有聪明的面试官才具备的能力。

    这里是通过继承和Unitest支持实现全状态机(FSM),这是使用私有/受保护接口的很好例子。

    这是一个关于问题的答案,C相当于朋友吗?为什么C不提供C++风格的"朋友"关键字?事实上,你的问题也是如此。


    我搜索了一下,发现这篇文章解释了如何使用私有接口为不同的客户机提供不同的接口。这是C++故事。

    我不认为这可以应用于c_tho,因为通过显式接口和将主机强制转换到适当接口的客户机可以实现相同的IMO效果。

    也许有人能看到我错过的东西……

    我在msdn上也发现了这个:

    Interface methods have public
    accessibility, which cannot be changed
    by the implementing type. An internal
    interface creates a contract that is
    not intended to be implemented outside
    the assembly that defines the
    interface. A public type that
    implements a method of an internal
    interface using the virtual modifier
    allows the method to be overridden by
    a derived type that is outside the
    assembly. If a second type in the
    defining assembly calls the method and
    expects an internal-only contract,
    behavior might be compromised when,
    instead, the overridden method in the
    outside assembly is executed. This
    creates a security vulnerability.


    就像内部类(也是私有的)一样,您可以在现有类中使用私有接口。