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

您所在的位置:网站首页 码农是什么职位 关于c#:什么是私有接口?

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

#关于c#:什么是私有接口? | 来源: 网络整理| 查看: 265

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

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

所以我想知道:

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

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

123456789101112131415161718public 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;     } }

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

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

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

123456789101112131415161718192021222324252627public 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。 @理查:不完全是==。显式接口实现并不一定意味着实现接口的方法是私有的。然而,在私有接口继承中,它们是特定的。显式实现可以使用不同名称的公共方法(例如,"close"用于实现IDisposable.Dispose)、具有相同名称的公共成员或私有成员来完成。后一种情况是真正创建私有接口继承——如果不强制转换到接口,就不能使用接口成员。 对不起,约翰,你错了,"显式接口实现并不一定意味着实现接口的方法是私有的"具体阅读我的答案中的链接文档:"显式接口成员实现包含访问修饰符是编译时错误"和"因为显式接口成员实现在方法调用或属性访问中,永远不能通过它们的完全限定名来访问离子,从某种意义上说,它们是私有的。但是,由于可以通过接口实例访问它们,因此它们在某种意义上也是公共的。" 更具体地说,如果有两个方法void do()和void ifoo.do()的ifoo void do()和foo类,那么非显式do方法与接口ifoo无关。您可以调用该方法,但只能在有一个foo(或其子类)的上下文中调用。只有当编译器知道foo是对象上的方法的唯一方式是接口ifoo时,才会调用ifoo实现。这就是.NET某些方面使用duck类型而不是强制接口使用的原因之一… …(foreach不使用ienumerable.getEnumerator()方法,它使用duck类型通过各种规则获取特定的getEnumerator,这些规则允许它选择不同于ienumerable的getEnumerator) 我接受纠正。这就是我在咖啡因之前阅读(更糟的是,张贴)的内容! 咖啡==好的:) @我觉得这是最好的答案。我终于有机会合并我的帐户,这样答案就可以被接受了。总之,一个非常糟糕的面试问题让我在接下来的面试中失去了信心! 太棒了,谢谢:)

从这个链接。

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:

1234567class 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:

1234PrivateImplementer 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).

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

相关讨论 嗨,马克,我也看到了那个网页-这不正是一个明确的接口实现,尽管? 我要+1这个,因为它被称为私有接口继承。 这是明确的接口实现,采访者说这不是他的意思。 当被问到是否意味着隐式和显式接口实现之间的"区别"时,采访者说:"不"。糟糕的面试官通常意味着工作不顺利。 是的,答案可能只是你的面试官是个混蛋。 +1;注意链接文章的最后一段,这解释了为什么您会/不会使用它。(是的,"你什么时候用X"可以适当地回答,"在实践中,不经常用。") 这就是一个可怕的问题。"你什么时候会使用你几乎肯定没有遇到过的这种模糊技术?"回答正确:几乎从来没有。回答错误:我不知道,我从来没有用过。我叫恶作剧。

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.

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3