¿Cuáles son las diferencias en la implementación de interfaces implícitamente y explícitamente en C#?

Cuándo se debe utilizar de manera implícita y cuándo se debe utilizar explícito?

Hay pros y/o contras a uno o al otro?


Microsoft directrices oficiales (de la primera edición Marco De Las Directrices De Diseño) los estados que el uso explícito de las implementaciones no son recomendables, ya que le da el código de comportamiento inesperado.

Creo que esta guía es muy válido en un pre-Cio-tiempo, cuando no pasan las cosas a su alrededor como las interfaces.

Podría alguien toca en ese aspecto así?

InformationsquelleAutor Seb Nilsson | 2008-09-27

12 Comentarios

  1. 471

    Implícito es cuando se define la interfaz a través de un miembro de su clase. Explícita es cuando se definen los métodos dentro de la clase en la interfaz. Sé que suena confuso, pero aquí es a lo que me refiero: IList.CopyTo sería implícitamente implementado como:

    public void CopyTo(Array array, int index)
    {
        throw new NotImplementedException();
    }

    y explícitamente como:

    void ICollection.CopyTo(Array array, int index)
    {
        throw new NotImplementedException();
    }

    Con la diferencia de que, implícitamente, es accesible a través de su clase que creó cuando se lance como que clase así como cuando su elenco como el de la interfaz. Explícita la aplicación le permite ser accesible sólo cuando se lanza como la propia interfaz.

    MyClass myClass = new MyClass(); //Declared as concrete class
    myclass.CopyTo //invalid with explicit
    ((IList)myClass).CopyTo //valid with explicit.

    Yo uso explícito principalmente para mantener la aplicación limpia, o cuando necesito dos implementaciones. Pero a pesar de que yo casi no la uso.

    Estoy seguro de que hay más razones para usar/no usar lo que otros post.

    Ver el siguiente post en este hilo de excelente razonamiento detrás de cada uno.

    • Sé que este post es viejo, pero me pareció muy útil – una cosa a tener en cuenta si no es claro, porque no era para mí fue que en el ejemplo de la implícitos uno tiene la public palabra clave…de lo contrario aparecerá un mensaje de error
    • Jeffrey Richter CLR a través de C# 4 ed ch 13 se muestra un ejemplo en el casting no es necesario: interna struct SomeValueType : IComparable { private Int32 m_x; public SomeValueType(Int32 x) { m_x = x; } public Int32 CompareTo(SomeValueType otros) {…);} Int32 IComparable.CompareTo(Object otros) { return CompareTo((SomeValueType) otros); } } public static void Main() { SomeValueType v = new SomeValueType(0); Object o = new Object(); Int32 n = v. CompareTo(v); // No de boxeo n = v. CompareTo(o); // error en tiempo de compilación }
    • ¿Tiene sentido, en cualquier caso, ambas implementaciones, Implícito y Explícito ?
    • Hoy me encontré con una situación rara que REQUIERE el uso de una explícita de la interfaz: Una clase con un campo generado por un generador de interfaz que crea el campo privado (Xamarin dirigidos a iOS, usando iOS storyboard). Y una interfaz donde tiene sentido para exponer ese campo (public readonly). Yo podría haber cambiado el nombre de la función de captador en la interfaz, pero el nombre actual fue el más lógico nombre para el objeto. Así que en lugar hice una implementación explícita referencia al campo privado: UISwitch IScoreRegPlayerViewCell.markerSwitch { get { return markerSwitch; } }.
    • Los horrores de la programación. Bueno, muy bien desacreditado!
  2. 193

    Definición implícita sería simplemente añadir los métodos /propiedades, etc. exigido por la interfaz directamente a la clase como métodos públicos.

    Definición explícita de las fuerzas de los miembros para ser expuestos sólo cuando se trabaja con la interfaz directamente, y no a la implementación subyacente. Este es el método preferido en la mayoría de los casos.

    1. Trabajando directamente con la interfaz, no reconociendo,
      de acoplamiento y el código para la implementación subyacente.
    2. En el caso de que usted ya tiene, digamos, un público Nombre de la propiedad en
      su código y desea implementar una interfaz que también tiene una
      Nombre de la propiedad, haciendo explícita la voluntad de mantener las dos por separado. Incluso
      si ellos estaban haciendo la misma cosa estaría todavía delegado de la explícita
      llame a la propiedad Name. Nunca se sabe, puede que desee cambiar
      cómo el Nombre de las obras para la clase normal y cómo el Nombre de la interfaz
      propiedad de las obras más adelante.
    3. En el caso de implementar una interfaz implícitamente, a continuación, la clase ahora expone
      nuevos comportamientos que podría ser relevante para un cliente de la
      la interfaz y eso significa que no mantener a sus clases sucinta
      suficiente (mi opinión).
    • Puedes hacer algunos buenos puntos aquí. especialmente A. me suele pasar mis clases en torno a la interconexión de todos modos, pero nunca he pensado realmente acerca de la forma en que la perspectiva.
    • No estoy seguro de que estoy de acuerdo con el punto C. Un Gato objeto de aplicar IEatable pero Comer() es una parte básica de la cosa. Habrá casos en los que usted quiere llamar a sólo Comer() en un Gato cuando se utiliza la ‘cruda’ objeto en lugar de a través de la IEatable interfaz, no?
    • Sé de algunos lugares donde Cat es, de hecho, IEatable sin objeciones.
    • Estoy totalmente en desacuerdo con todo lo anterior, y diría que el uso de interfaces explícitas es la receta del desastre y de la no programación orientada a objetos o INUNDACIÓN, por su definición ( véase mi respuesta sobre el polimorfismo)
    • Kuzub: en Primer lugar, no he podido encontrar ninguna respuesta a su nombre en el polimorfismo. En segundo lugar, hay muchos casos donde explícito implementaitons son necesarios. Desde una perspectiva académica puede tener argumentos para «OOP» racional. De un bien rendimiento código perspectiva de que uno no puede argumentar la necesidad de que esta implementación en el contexto correcto. Me encontré con esto la primera vez que traté de crear un loosley junto aplicación de N-Tier. El abiltiy para pasar los datos a través de interfaces fue crucial, evitando sin embargo downcasting y colisión de nombres en una fábrica modelo impedido verdadera disociación.
    • Véase También: stackoverflow.com/questions/4103300/…

  3. 65

    Además de las excelentes respuestas que ya están disponibles, hay algunos casos donde implementación explícita es NECESARIO para que el compilador sea capaz de averiguar lo que se requiere. Echa un vistazo a IEnumerable<T> como un primer ejemplo de que es probable que venir para arriba con bastante frecuencia.

    He aquí un ejemplo:

    public abstract class StringList : IEnumerable<string>
    {
        private string[] _list = new string[] {"foo", "bar", "baz"};
    
        //...
    
        #region IEnumerable<string> Members
        public IEnumerator<string> GetEnumerator()
        {
            foreach (string s in _list)
            { yield return s; }
        }
        #endregion
    
        #region IEnumerable Members
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
        #endregion
    }

    Aquí, IEnumerable<string> implementa IEnumerable, por lo tanto necesitamos demasiado. Pero espera, tanto el genérico y el de la versión normal implementar funciones con el mismo método de firma (C# ignora el tipo de retorno para esto). Esto es completamente legal y fina. ¿Cómo funciona el compilador de resolver que el uso? Esto obliga a que sólo tienen, en la mayoría, una definición implícita, entonces se puede resolver lo que necesita.

    es decir.

    StringList sl = new StringList();
    
    //uses the implicit definition.
    IEnumerator<string> enumerableString = sl.GetEnumerator();
    //same as above, only a little more explicit.
    IEnumerator<string> enumerableString2 = ((IEnumerable<string>)sl).GetEnumerator();
    //returns the same as above, but via the explicit definition
    IEnumerator enumerableStuff = ((IEnumerable)sl).GetEnumerator();

    PS: El pequeño pedazo de direccionamiento indirecto en la definición explícita de IEnumerable funciona porque dentro de la función, el compilador sabe que el tipo de la variable es un Fconnectionlog, y eso es lo que resuelve la llamada a la función. Ingenioso poco hecho para la implementación de algunas de las capas de abstracción de algunos de los .NET core interfaces parece que se han acumulado.

    • por qué su clase es abstracta
    • Después de 2 años, todo lo que puedo decir es «Buena pregunta». No tengo ni idea, salvo tal vez que he copiado de que el código de algo que yo estaba trabajando en donde se abstract.
    • No debería dar error en Fconnectionlog sl = new Fconnectionlog();
    • estás en lo correcto, pero creo que el punto de Mateo Scharley el post de arriba no se pierde.
  4. 32

    Razón #1

    Que tienden a un uso explícito de la interfaz de la aplicación cuando quiero desalentar a «programación de una aplicación» (Principios de diseño de Patrones de Diseño).

    Por ejemplo, en un MVPaplicación web basada en:

    public interface INavigator {
        void Redirect(string url);
    }
    
    public sealed class StandardNavigator : INavigator {
        void INavigator.Redirect(string url) {
            Response.Redirect(url);
        }
    }

    Ahora otra clase (tales como presentador) es menos probable que dependen de la StandardNavigator aplicación y es más probable que dependen de la INavigator interfaz (ya que la aplicación tendría que ser arrojado a una interfaz para hacer uso de el método Redirect).

    Razón #2

    Otra razón puede ser que con un explícito de la interfaz de la aplicación, sería mantener una clase del «default» de la interfaz más limpia. Por ejemplo, si yo fuera el desarrollo de un ASP.NET control de servidor, puede ser que quiera dos interfaces:

    1. La clase principal de la interfaz, que es utilizado por los desarrolladores de páginas web; y
    2. Un «oculto» de la interfaz utilizada por el presentador que puedo desarrollar para manejar el control de la lógica de

    A continuación un ejemplo sencillo. Es un control de cuadro combinado que las listas de clientes. En este ejemplo, la página web del desarrollador no está interesado en llenar la lista; en lugar de eso, ellos sólo quieren ser capaces de seleccionar a un cliente por el GUID o para obtener del cliente seleccionado del GUID. Un presentador rellena la casilla en la primera carga de la página, y este presentador es encapsulado por el control.

    public sealed class CustomerComboBox : ComboBox, ICustomerComboBox {
        private readonly CustomerComboBoxPresenter presenter;
    
        public CustomerComboBox() {
            presenter = new CustomerComboBoxPresenter(this);
        }
    
        protected override void OnLoad() {
            if (!Page.IsPostBack) presenter.HandleFirstLoad();
        }
    
        //Primary interface used by web page developers
        public Guid ClientId {
            get { return new Guid(SelectedItem.Value); }
            set { SelectedItem.Value = value.ToString(); }
        }
    
        //"Hidden" interface used by presenter
        IEnumerable<CustomerDto> ICustomerComboBox.DataSource { set; }
    }

    El presentador rellena el origen de datos, y el desarrollador de páginas web nunca debe ser consciente de su existencia.

    Pero No Es una Bala de Plata

    Yo no recomendaría siempre empleando explícita implementaciones de interfaz. Esos son sólo dos ejemplos en los que podría ser útil.

  5. 32

    Citar Jeffrey Richter de CLR a través de C#

    (EIMI significa Explicit menterface Mmétodo memplantación)

    Es críticamente importante para usted
    entender algunas ramificaciones que
    existe cuando se utiliza EIMIs. Y porque de
    estas ramificaciones, usted debe tratar de
    evitar EIMIs tanto como sea posible.
    Afortunadamente, las interfaces genéricas ayuda
    evitar EIMIs bastante. Pero no
    todavía puede haber momentos en que usted necesita
    el uso de ellas (tales como la ejecución de dos
    la interfaz de los métodos con el mismo nombre
    y firma). Aquí están los grandes
    problemas con EIMIs:

    • No hay ninguna documentación que explica cómo un tipo específicamente
      implementa un EIMI método, y no
      no es de Microsoft Visual Studio
      IntelliSense apoyo.
    • Tipo de valor instancias de la caja cuando se lanza a una interfaz.
    • Un EIMI no puede ser llamado por un tipo derivado.

    Si utiliza una referencia de la interfaz de CUALQUIER virtual de la cadena puede ser explícitamente reemplazado con EIMI en cualquier clase derivada y cuando un objeto de este tipo se lanza a la interfaz, virtual de la cadena es ignorado y la implementación explícita se llama. Que es nada, pero el polimorfismo.

    EIMIs también puede ser utilizado para ocultar no inflexible de los miembros de la interfaz de Marco básico Interfaces’ implementaciones como IEnumerable<T> por lo que su clase no exponer no inflexible método directamente, pero es correcta sintáctica.

    • Re-implementación de interfaces, aunque legal, generalmente es dudosa en el mejor. Explícito de las implementaciones deben, generalmente, de la cadena a un método virtual, ya sea directamente, o a través de la envoltura de la lógica que debe ser vinculante para las clases derivadas. Mientras que es ciertamente posible utilizar las interfaces en las maneras que son hostiles para la adecuada programación orientada a objetos convenciones, eso no significa que no puedan utilizarse mejor.
    • Lo EIMI y IEMI representan?
    • Explícito De La Interfaz De La Implementación Del Método
    • A continuación, debe IEMI no se IIMI?
    • -1 de «Generalmente veo las Interfaces como Semi (en el mejor), característica de la programación orientada a objetos, proporciona la herencia, pero no a la real polimorfismo.» Estoy totalmente en desacuerdo. Muy por el contrario, las interfaces son todos acerca de polimorfismo y no son principalmente acerca de la herencia. Ellos atribuyen múltiples clasificaciones a un tipo. Evitar IEMI, cuando se puede, y delegado, como @supercat sugerido, cuando usted no puede. No evitar las interfaces.
    • «Un EIMI no puede ser llamado por un tipo derivado.» << ¿QUÉ? Eso no es cierto. Si me explícitamente implementar una interfaz en un tipo, entonces yo se derivan de ese tipo, todavía puedo echarlo a la interfaz para llamar al método, exactamente como me gustaría tener a para que el tipo se implementa en. No tan seguro de lo que estás hablando. Incluso dentro de los derivados de tipo, simplemente puedo elenco de «este» a la interfaz en cuestión para llegar a la forma explícita método implementado.

  6. 19

    Además de otros motivos ya expuestos, esta es la situación en la que una clase es la implementación de dos interfaces diferentes que tienen una propiedad/método con el mismo nombre y la firma.

    ///<summary>
    ///This is a Book
    ///</summary>
    interface IBook
    {
        string Title { get; }
        string ISBN { get; }
    }
    
    ///<summary>
    ///This is a Person
    ///</summary>
    interface IPerson
    {
        string Title { get; }
        string Forename { get; }
        string Surname { get; }
    }
    
    ///<summary>
    ///This is some freaky book-person.
    ///</summary>
    class Class1 : IBook, IPerson
    {
        ///<summary>
        ///This method is shared by both Book and Person
        ///</summary>
        public string Title
        {
            get
            {
                string personTitle = "Mr";
                string bookTitle = "The Hitchhikers Guide to the Galaxy";
    
                //What do we do here?
                return null;
            }
        }
    
        #region IPerson Members
    
        public string Forename
        {
            get { return "Lee"; }
        }
    
        public string Surname
        {
            get { return "Oades"; }
        }
    
        #endregion
    
        #region IBook Members
    
        public string ISBN
        {
            get { return "1-904048-46-3"; }
        }
    
        #endregion
    }

    Este código se compila y se ejecuta bien, pero el Título de propiedad es compartida.

    Claramente, queremos el valor de Título volvió a depender de si estábamos tratando de Class1 como un Libro o una Persona. Esto es cuando podemos utilizar el explícito de la interfaz.

    string IBook.Title
    {
        get
        {
            return "The Hitchhikers Guide to the Galaxy";
        }
    }
    
    string IPerson.Title
    {
        get
        {
            return "Mr";
        }
    }
    
    public string Title
    {
        get { return "Still shared"; }
    }

    Aviso de que el explícitas las definiciones de interfaz se infiere que el Público – y por lo tanto usted no puede declarar a ser público (o lo contrario) de forma explícita.

    Nota también de que todavía puede tener una «compartida» de la versión (como se muestra arriba), pero mientras que esto es posible, la existencia de este tipo de propiedad es cuestionable. Tal vez podría ser utilizado como una implementación predeterminada de Título -, de modo que el código existente no tendrían que ser modificados para lanzar Class1 a IBook o IPerson.

    Si no se define el «compartir» (implícita) de Título, los consumidores de Class1 debe explícitamente instancias de Class1 a IBook o IPerson primer caso contrario, el código no compila.

  7. 15

    Yo uso explícito de la interfaz de la aplicación la mayoría del tiempo. Estas son las razones principales.

    Refactorización es más seguro

    Al cambiar de una interfaz, es mejor si el compilador puede comprobar. Esto es más difícil con el implícito de las implementaciones.

    Dos casos comunes vienen a la mente:

    • La adición de una función a una interfaz, cuando una clase que implementa esta interfaz ya pasa a tener un método con la misma firma que el nuevo. Esto puede provocar un comportamiento inesperado, y ha mordido me duro varias veces. Es difícil «ver» cuando la depuración debido a que la función es probable que no se encuentra con los otros métodos de interfaz en el archivo (la auto-documentación de los temas mencionados a continuación).

    • La eliminación de una función a partir de una interfaz. Implícitamente aplicado los métodos de repente será de código muerto, pero implementado explícitamente los métodos de quedar atrapados por error de compilación. Incluso si el código muerto es bueno tener de todo, quiero ser obligadas a revisar y promover que.

    Es lamentable que C# no tiene una palabra clave que nos obliga a marcar un método implícito de implementación, por lo que el compilador podría hacer el cheque extra. Métodos virtuales no tiene ninguno de los problemas mencionados, debido a que se requiere el uso de ‘anulación’ y ‘nuevo’.

    Nota: para fijo o rara vez-cambio de interfaces (típicamente del proveedor de la API), esto no es un problema. Para mis propias interfaces, aunque no puedo predecir cuándo/cómo van a cambiar.

    Se auto-documentación de

    Si veo ‘public bool Execute()’ en una clase, se va a tomar un trabajo adicional para averiguar que es parte de una interfaz. Probablemente alguien tendrá que comentar que lo diga, o ponerlo en un grupo de otras implementaciones de interfaz, todo bajo una región o agrupación comentario diciendo «la aplicación de ITask». Por supuesto, que sólo funciona si el encabezado de grupo no está fuera de la pantalla..

    Considerando que: ‘bool ITask.Execute()’ es claro y sin ambigüedades.

    Clara separación de la interfaz de la aplicación

    Creo que de interfaces como más «público» de métodos públicos porque están diseñados para exponer un poco de la superficie del hormigón tipo. Reducen el tipo de una capacidad, un comportamiento, un conjunto de rasgos, etc. Y en la aplicación, creo que es útil para mantener esta separación.

    Como estoy mirando a través de una clase de código, cuando vengo a través explícita implementaciones de interfaz, mi cerebro se cambia a «código de contrato» de modo. A menudo estas implementaciones simplemente reenviar a otros métodos, pero a veces van a hacer un extra de estado/param comprobación, la conversión de la entrada de parámetros para adaptarse mejor a los requerimientos internos, o incluso de la traducción para el control de versiones de los efectos (es decir, varias generaciones de interfaces de todos los despejes de abajo a la implementación común).

    (Me doy cuenta de que los públicos son también contratos de código, pero interfaces son mucho más fuertes, sobre todo en una interfaz impulsado por codebase donde el uso directo de tipos concretos es generalmente un signo de interna-sólo el código).

    Relacionados con: Razón 2 anterior por Jon.

    Y así sucesivamente

    Además de las ventajas ya mencionadas en otras respuestas aquí:

    Problemas

    No es todo diversión y felicidad. Hay algunos casos en los que me quedo con la implicits:

    • Tipos de valor, debido a que se requieren de boxeo y menor perf. Esto no es una regla estricta, y depende de la interfaz y cómo es que está destinado a ser utilizado. IComparable? Implícito. IFormattable? Probablemente explícito.
    • Trivial de las interfaces del sistema que tienen métodos que son frecuentemente llamados directamente (como IDisposable.Disponer).

    También, puede ser un dolor de cabeza para hacer el casting cuando de hecho tienen el tipo concreto y quieres llamar a un explícito del método de interfaz. Estoy de acuerdo con esto de dos maneras:

    1. Agregar los públicos y tiene la interfaz de los métodos adelante a ellos para la aplicación. En general, ocurre con más simples interfaces cuando se trabaja internamente.
    2. (Mi método preferido) Agregar un public IMyInterface I { get { return this; } } (que debería recibir entre líneas) y llame a foo.I.InterfaceMethod(). Si múltiples interfaces que necesitan esta capacidad, expanda el nombre más allá de que yo (en mi experiencia, es raro que tengo esta necesidad).
  8. 8

    Si se implementa de forma explícita, usted sólo será capaz de hacer referencia a los miembros de la interfaz a través de una referencia que es del tipo de la interfaz. Una referencia que es el tipo de la clase de implementación no exponer a los miembros de la interfaz.

    Si su clase de implementación no es pública, excepto para el método utilizado para crear la clase (que podría ser una fábrica o Coi contenedor), y a excepción de los métodos de interfaz (por supuesto), entonces no veo ninguna ventaja explícitamente la implementación de interfaces.

    De otra manera, de forma explícita la implementación de interfaces se asegura de que las referencias a su concreta implementación de la clase no se utilizan, lo que le permite cambiar de que la implementación en un momento posterior. «Se asegura», supongo, es la «ventaja». Un factor de la aplicación puede lograr esto sin la implementación explícita.

    La desventaja, en mi opinión, es que usted se encontrará fundición de tipos a/desde la interfaz de la aplicación el código que tiene acceso a los miembros públicos.

    Como muchas cosas, la ventaja es la desventaja (y viceversa). Explícitamente la implementación de interfaces se asegurará de que su clase concreta la ejecución de código no está expuesto.

    • Bonita respuesta, Bill. Las otras respuestas fueron muy grande, pero usted siempre algún objetivo adicional de los puntos de vista (en la parte superior de sus opiniones) que hizo más fácil para mí entender. Como la mayoría de cosas que hay pros y contras con implícito o explícito de las implementaciones por lo que sólo tiene que utilizar el mejor para su particular escenario o caso de uso. Me gustaría decir a aquellos que tratan a la mejor figura que se benefician de la lectura de su respuesta.
  9. 6

    Implícita una implementación de la interfaz es donde usted tiene un método con la misma firma de la interfaz.

    Explícito de la interfaz de la aplicación es donde se declara explícitamente que la interfaz del método pertenece.

    interface I1
    {
        void implicitExample();
    }
    
    interface I2
    {
        void explicitExample();
    }
    
    
    class C : I1, I2
    {
        void implicitExample()
        {
            Console.WriteLine("I1.implicitExample()");
        }
    
    
        void I2.explicitExample()
        {
            Console.WriteLine("I2.explicitExample()");
        }
    }

    De MSDN: implícito y explícito de implementaciones de interfaz

  10. 6

    Cada miembro de la clase que implementa una interfaz de exportaciones de una declaración que es semánticamente similar a la forma en que VB.NET declaraciones de interfaz están escritas, por ejemplo,

    Public Overridable Function Foo() As Integer Implements IFoo.Foo

    Aunque el nombre del miembro de la clase menudo coincide con el de miembro de interfaz, y el miembro de la clase a menudo serán públicas, ni de esas cosas es necesario. Uno también puede declarar:

    Protected Overridable Function IFoo_Foo() As Integer Implements IFoo.Foo

    En cuyo caso la clase y sus derivados sería permitido el acceso a un miembro de la clase utilizando el nombre IFoo_Foo, pero el mundo exterior sólo sería capaz de acceder a ese miembro en particular por la fundición a la IFoo. Este enfoque a menudo es bueno en los casos en que un método de interfaz tendrá especificado comportamiento en todas las implementaciones, pero útil comportamiento en sólo algunos [por ejemplo, el comportamiento especificado para una lectura única de la colección de IList<T>.Add método es lanzar NotSupportedException]. Por desgracia, la única manera correcta para implementar la interfaz en C# es:

    int IFoo.Foo() { return IFoo_Foo(); }
    protected virtual int IFoo_Foo() { ... real code goes here ... }

    No es tan bonito.

  11. 2

    Un importante uso explícito de la interfaz de la aplicación es cuando se necesita para implementar interfaces con mixto visibilidad.

    El problema y la solución están bien explicadas en el artículo C# Interfaz Interna.

    Por ejemplo, si usted quiere proteger la fuga de objetos entre capas de aplicación, esta técnica permite especificar diferentes visibilidad de los miembros que podría causar la fuga.

  12. 1

    Las respuestas anteriores explican por qué la implementación de una interfaz de forma explícita en C# puede ser de la copa de (para la mayoría razones formales). Sin embargo, hay una situación en la implementación explícita es obligatorio: con el fin De evitar fugas, la encapsulación cuando la interfaz no espublic, pero la clase de implementación es public.

    //Given:
    internal interface I { void M(); }
    
    //Then explicit implementation correctly observes encapsulation of I:
    //Both ((I)CExplicit).M and CExplicit.M are accessible only internally.
    public class CExplicit: I { void I.M() { } }
    
    //However, implicit implementation breaks encapsulation of I, because
    //((I)CImplicit).M is only accessible internally, while CImplicit.M is accessible publicly.
    public class CImplicit: I { public void M() { } }

    Por encima de la fuga es inevitable porque, según el C# especificación, «Todos los miembros de la interfaz implícitamente tienen acceso público.» Como consecuencia, implícita implementaciones deben también dar public acceso, incluso si la interfaz en sí, por ejemplo, es internal.

    Implícita la implementación de una interfaz en C# es una gran comodidad. En la práctica, muchos de los programadores utilizar todo el tiempo/en todas partes sin más consideración. Esto conduce a la desordenado tipo de superficies, en el mejor y se filtró la encapsulación en el peor. Otros idiomas, como el F#, incluso no permitir que se.

Dejar respuesta

Please enter your comment!
Please enter your name here