Si tengo

public class AImplementation:IAInterface
{
   void IAInterface.AInterfaceMethod()
   {
   }

   void AnotherMethod()
   {
      ((IAInterface)this).AInterfaceMethod();
   }
}

Cómo llamar a AInterfaceMethod() de AnotherMethod() sin una conversión explícita?

  • ¿Cuál es el problema con el elenco?
  • Yo sólo frunció el ceño cuando descubrí esta característica del lenguaje. Es muy útil cuando la aplicación de algunas interfaces como ICloneable aunque.
  • ¿Por qué no hacerlo de la otra manera alrededor, entonces? Mover el código a partir de la explícita del método de interfaz a un estado «normal» del método. A continuación, sólo dejar que todos los métodos (incluyendo la explícita del método de interfaz) llamar a ese método.
  • En mi humilde opinión, @adrianm el comentario de arriba es la mejor respuesta aquí! [Y es un buen refactorización cuando se encuentra con esta situación, o si se espera que la necesidad de este.]
  • Por lo que vale en casi todos los casos, una «solución» es a cambio de que un método de una forma implícita de la aplicación, para permitir el acceso interno, mientras que la satisfacción de la interfaz de contrato. La desventaja es que esto se hace declarando el miembro public (y la eliminación de la explícita IAInterface. de la declaración), que hace que sea más ampliamente visible de lo que usted podría desear. Así que no estoy recomendando este, sólo mencionarla como una solución alternativa que es posible.
InformationsquelleAutor Jader Dias | 2009-12-08

7 Comentarios

  1. 68

    Un número de respuestas dicen que no se puede. Son incorrectas. Hay un montón de maneras de hacer esto sin usar el operador de conversión.

    Técnica #1: el Uso de «como» operador de operador de conversión.

    void AnotherMethod()   
    {      
        (this as IAInterface).AInterfaceMethod();  //no cast here
    }

    Técnica #2: uso de una conversión implícita a través de una variable local.

    void AnotherMethod()   
    {      
        IAInterface ia = this;
        ia.AInterfaceMethod();  //no cast here either
    }

    Técnica #3: escribir un método de extensión:

    static class Extensions
    {
        public static void DoIt(this IAInterface ia)
        {
            ia.AInterfaceMethod(); //no cast here!
        }
    }
    ...
    void AnotherMethod()   
    {      
        this.DoIt();  //no cast here either!
    }

    Técnica #4: Introducir un ayudante:

    private IAInterface AsIA => this;
    void AnotherMethod()   
    {      
        this.AsIA.IAInterfaceMethod();  //no casts here!
    }
    • Para ser pedante, él no le pidió que no se utilice el «operador de conversión», pidió que «sin una conversión explícita», y creo que, en general, operador de as sería considerado como «una conversión explícita» (ni idea de si eso es correcto en términos de lenguaje de especificación de definiciones, o si la pregunta es de sentido en ese contexto).
    • Así, la semántica del operador de conversión y la semántica del operador como son bastante diferentes, así que es un error lógico se identificara con ellos. Consulte beta.blogs.msdn.com/ericlippert/archive/2009/10/08/… para obtener más detalles.
    • Sé que esto es bastante antiguo, pero me topé con esta pregunta de hoy. Estoy en lo cierto al pensar que la «mejor» manera implícita es la fundición de uno? Esto ofrece el mejor tiempo de compilación de protección para el código que estoy en lo cierto? Si me fue bien con el bastidor o el «como» de la operación (que en realidad no tiene sentido en este contexto, ya que SE supone que el objeto de implementar la interfaz en el primer lugar) me corre el riesgo de tratar de poner a un inválido interfaz me da un error en tiempo de ejecución. Si trato de conversión implícita a una interfaz en la que la clase no implementa, me sale un error de tiempo de compilación en lugar de eso, es mucho mejor.
    • Que hacer un argumento convincente.
    • Yo abajo votado porque todas las técnicas mencionadas arruinar la llamada en caso de herencia, es decir, si usted está tratando de llamar la implementación del método de la clase a y la instancia de la clase B, la cual hereda de la clase a, a continuación, de todas las maneras mencionadas van a llamar a la B aplicación. No sé una manera de llamar a la aplicación sin necesidad de utilizar la reflexión.
    • Si la clase B se ha re-implementado la interfaz, a continuación, su aplicación es correcto para un receptor de tipo B; bajo qué circunstancias usted desea llamar a la mal método? El autor de la más clase derivada tiene más información que el autor de al menos clase derivada, por lo que el autor de la clase derivada debe decidir cuál es la semántica.
    • Considere la posibilidad de Una clase (clase base) implementa la interfaz I1 explícitamente. Otro de la clase B hereda de la clase a y anula I1 es decir, la aplicación implementa es así y tiene que llamar a la base de la aplicación (de clase). Si Una de implementar I1 implícitamente, a continuación, que no era un problema (de la base.MethodDeclaredInI1). ¿Qué debo hacer si la interfaz es implementada de forma explícita por parte de la clase? La reflexión es mi respuesta. Su respuesta es buena. Anexar el caso y va a ser completo.
    • Si el autor de la clase A tiene la intención de que una clase derivada debe ser capaz de llamar y/o anular la implementación de la clase base, a continuación, el autor de la clase A debe hacer un protegidas método virtual en lugar de una explícita del método de interfaz. Si el autor de la clase A no tiene la intención de que, y el autor de la clase B deseos de que el autor de la clase A había hecho hasta entonces, el autor de la clase B debería (1) encontrar una clase diferente a extender, tal vez por la escritura de sus propios, o (2) negociar con el autor de la clase A. la Herencia debe ser diseñado en función de una clase.
    • El «¿Cuál es la diferencia…?» post en el blog que Eric Lippert se refiere a que en los comentarios de arriba es ahora en blogs.msdn.microsoft.com/ericlippert/2009/10/08/…

  2. 9

    Puede introducir un auxiliar de la propiedad privada:

    private IAInterface IAInterface => this;
    
    void IAInterface.AInterfaceMethod()
    {
    }
    
    void AnotherMethod()
    {
       IAInterface.AInterfaceMethod();
    }
  3. 8

    Esta probado y funciona…

    public class AImplementation : IAInterface
    {
        IAInterface IAInterface;
    
        public AImplementation() {
            IAInterface = (IAInterface)this;
        }
    
        void IAInterface.AInterfaceMethod()
        {
        }
    
        void AnotherMethod()
        {
           IAInterface.AInterfaceMethod();
        }
    }
    • Usted no tiene que explícitamente que esto IAInterface
  4. 2

    Y otra manera (que es un spin off de Eric Técnica #2 y también debería dar un error de tiempo de compilación si la interfaz no está implementado)

         IAInterface AsIAInterface
         {
            get { return this; }
         }
    • Creo que esto es mejor que Eric técnica #2 – SI se prevé la necesidad de acceso a otro método de interfaz de referencias en más de un método en la interfaz.
  5. 0

    No se puede, pero si usted tiene que hacer muchas cosas que usted puede definir una comodidad helper:

    private IAInterface that { get { return (IAInterface)this; } }

    Cada vez que usted quiere llamar a un método de interfaz que se ha implementado de forma explícita puede utilizar that.method() en lugar de ((IAInterface)this).method().

    • Vale la pena señalar que no se necesita una conversión explícita aquí (ya que no hay una conversión implícita de this a IAInterface que se implementa).
  6. 0

    De otra manera (que no mejor):

    (this ?? default(IAInterface)).AInterfaceMethod();
    • Teniendo en cuenta lo que el compilador hace para hacer este trabajo, esto es simplemente un engorroso manera de decir ((IAInterface)this), con el inconveniente añadido de que si this es null, y no se le supone, se hará un llamado a AInterfaceMethod en una instancia predeterminada de su clase, en lugar de lanzar una excepción. Casi sin duda no quería comportamiento.
  7. -3

    No puede usted acaba de quitar el «IAInterface.» a partir de la firma del método?

    public class AImplementation : IAInterface
    {
       public void AInterfaceMethod()
       {
       }
    
       void AnotherMethod()
       {
          this.AInterfaceMethod();
       }
    }
    • Entonces no va a ser una implementación explícita.

Dejar respuesta

Please enter your comment!
Please enter your name here