2009-04-27 17 views
43

En una entrevista hace un tiempo para una posición de .NET, el entrevistador me preguntó "¿para qué usarías una interfaz privada?".¿Qué es una interfaz privada?

Le pregunté si se refería a la diferencia entre la implementación de la interfaz implícita frente a la explícita a la que respondió no.

Así que me pregunto:

  1. lo que quería decir?
  2. ¿Para qué utilizarías una interfaz privada?

Respuesta

30

Una interfaz puede ser privada dentro de otra clase

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

en términos de utilidad, simplemente oculta a otro código, incluso dentro del mismo conjunto, que existe dicho interfaz. La utilidad de esto no es terriblemente alta en mi opinión.

Explicit interface implementation es una cuestión diferente, tiene algunos casos muy útiles (especialmente cuando se trabaja con genéricos y otras interfaces no genéricas) pero no lo llamaría 'interfaces privadas' y no diría que el término se usa comúnmente de esa manera .

Usando las dos técnicas en conjunto que puede hacer:

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 
    } 
} 

Esto le permite exponer las clases anidadas de alguna manera al tiempo que permite la clase padre para invocar métodos en los que el mundo exterior no puede. Este es un caso potencialmente útil, pero no es algo que desearía usar con mucha frecuencia. Ciertamente, su uso en una entrevista suena a ser un caso límite que el entrevistador está usando porque lo han visto y aunque fue 'interesante'

+5

Aunque eso es cierto, ¿no sería ese uno de los usos más inútiles de las interfaces? No puedo entender por qué alguna vez usarías tal construcción. – Razzie

+0

esforzándose por pensar en un caso de uso para eso, o al menos en un caso de uso que no implique también crear una clase divina – annakata

+0

Eso es lo que interpreté como una pregunta, en cuyo caso fue solo una pregunta tonta entrevistador preguntado! – RichardOD

11

De this link.

herencia de interfaces privada

Históricamente, las lenguas han permitido la herencia privada. En C++, puede heredar de un tipo sin ser polimórficamente compatible con ese tipo. Es solo una forma conveniente de reutilizar una implementación. En el CTS, no puede hacer la herencia de implementación privada. Pero puedes usar herencia de interfaz privada.

La herencia de interfaz privada es realmente solo una forma de ocultar métodos de la API pública de un tipo. Se compilan en métodos privados, pero en realidad son accesibles a través del mapa de interfaz de un tipo. En otras palabras, solo se pueden llamar a través de una referencia escrita como la interfaz en la que se define el método. Un ejemplo hará esto más fácil de entender:

class PrivateImplementer : IFoo 
{ 
    void IFoo.Foo() 
    { 
     Console.WriteLine("PrivateImplementer::IFoo.Foo"); 
    } 
} 

En este caso, PrivateImplementer se sabe públicamente a aplicar IFoo. Por lo tanto, una instancia puede tratarse polimórficamente como una instancia de IFoo. Pero no puedes llamar a Foo, a menos que lo trates como IFoo. Este código demuestra esto:

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

Puede seleccionar métodos individuales de una interfaz para implementar de forma privada. Por ejemplo, si PrivateImplementer implementó IFooBar, puede optar por implementar Foo de forma privada, pero Bar utiliza públicamente la sintaxis ordinaria.

En la práctica, no hay muchos casos comunes en los que utilizaría la implementación privada. La biblioteca System.Collections.Generic utiliza este enfoque para implementar en secreto todas las interfaces heredadas System.Collections heredadas. Esto hace que la compatibilidad con versiones anteriores "simplemente funcione", por ejemplo, pasar una instancia de List<T> a un método que espera que un IList funcione bien. En este ejemplo específico, abarrotar las nuevas API de tipo habría sido una pena (hay bastantes métodos necesarios para la interoperabilidad de tipo débil).

"No" es una respuesta bastante pobre si estaba buscando averiguar lo que sabía. Parece alguien que solo quiere mostrar cuánto saben.

+2

Hola Mark, también vi esa página web, ¿no es eso lo mismo que una implementación de interfaz explícita? – RichardOD

+1

Voy a hacer +1 porque se conoce como herencia de interfaz privada. – annakata

+6

Esa es la implementación explícita de la interfaz y el entrevistador dijo que NO era lo que quería decir. – GrahamS

1

Al igual que una clase interna (que también es privada) puede usar una interfaz privada en una clase existente.

1

Busqué en Google un poco y encontré el artículo this que explica cómo las interfaces privadas se pueden usar para proporcionar diferentes interfaces a diferentes clientes. Esta es la historia de C++.

No creo que esto pueda aplicarse a C# tho, porque el mismo efecto IMO se puede lograr con interfaces explícitas y clientes que emiten host a la interfaz adecuada.

Tal vez alguien más puede ver algo que había perdido allí ....

También encontré esto en MSDN:

métodos de interfaz tienen acceso público, que no puede ser cambiado por el tipo implementación . Una interfaz interna crea un contrato que es no destinado a ser implementado fuera del el conjunto que define la interfaz . Un tipo público que implementa un método de una interfaz interna utilizando el modificador virtual permite anular el método por un tipo derivado que está fuera del ensamblaje . Si un segundo tipo en el ensamblado de definición llama al método y espera un contrato solo interno, el comportamiento podría verse comprometido cuando, en su lugar, se ejecute el método reemplazado en el ensamblaje externo fuera de . Este crea una vulnerabilidad de seguridad.

2

ShuggyCoUk da buena respuesta pero con tal comentario

Este es un caso potencialmente útil, pero no es algo que desearía utilizar muy a menudo. Ciertamente su uso en una entrevista huele a ser un caso límite de que el entrevistador está utilizando porque han visto y aunque era 'interesante'

que, debo decir, que no es sin duda la capacidad de los entrevistadores sólo es inteligente.

Aquí está Realization of Full State Machine (FSM) with inheritance and unitest support, que es un buen ejemplo del uso de interfaces privadas/protegidas.

Fue una respuesta a las preguntas What is the C# equivalent of friend? y Why does C# not provide the C++ style 'friend' keyword? y, de hecho, en su pregunta también.

Cuestiones relacionadas