Pregunta

Tengo una interfaz C # con ciertos parámetros de método declarados como tipos object . Sin embargo, el tipo real que se pasa puede variar según la clase que implementa la interfaz:

public interface IMyInterface
{
    void MyMethod(object arg);
}

public class MyClass1 : IMyInterface
{
    public void MyMethod(object arg)
    {
        MyObject obj = (MyObject) arg;
        // do something with obj...
    }
}

public class MyClass2 : IMyInterface
{
    public void MyMethod(object arg)
    {
        byte[] obj = (byte[]) arg;
        // do something with obj...
    }
}

El problema con MyClass2 es que la conversión de byte [] hacia y desde object es boxing y unboxing , que son operaciones computacionalmente costosas que afectan el rendimiento.

¿Resolvería este problema con una interfaz genérica para evitar el boxing / unboxing ?

public interface IMyInterface<T>
{
    void MyMethod(T arg);
}

public class MyClass1 : IMyInterface<MyObject>
{
    public void MyMethod(MyObject arg)
    {
        // typecast no longer necessary
        //MyObject obj = (MyObject) arg;
        // do something with arg...
    }
}

public class MyClass2 : IMyInterface<byte[]>
{
    public void MyMethod(byte[] arg)
    {
        // typecast no longer necessary
        //byte[] obj = (byte[]) arg;
        // do something with arg...
    }
}

¿Cómo se implementa esto en .NET vs Mono? ¿Habrá implicaciones de rendimiento en cualquiera de las plataformas?

¡Gracias!

¿Fue útil?

Solución

No estoy seguro de cómo se implementa en mono, pero las interfaces genéricas ayudarán porque el compilador crea una nueva función del tipo específico para cada tipo diferente utilizado (internamente, hay algunos casos en los que puede utilizar el mismo función generada). Si se genera una función del tipo específico, no hay necesidad de encuadrar / desempaquetar el tipo.

Esta es la razón por la cual la biblioteca Collections.Generic fue un gran éxito en .NET 2.0 porque las colecciones ya no requerían boxeo y se volvieron significativamente más eficientes.

Otros consejos

Obtendrá los mismos beneficios en Mono que en .NET.

Recomendamos encarecidamente que utilice Mono 1.9 o Mono 2.0 RCx en general, ya que el soporte genérico solo maduró con 1.9.

  

El problema con MyClass2 es que el   conversión de byte [] ay desde   objeto es boxeo y unboxing, que   son computacionalmente caros   operaciones que afectan el rendimiento.

No hay ningún boxeo relacionado con los tipos de matriz, incluso uno con elementos de tipo de valor. Una matriz es un tipo de referencia.

La sobrecarga en (byte []) arg es mínima en el mejor de los casos.

Sí, en .Net (MS no está seguro acerca de los mono) los genéricos se implementan en el momento de la compilación, por lo que no hay ningún tipo de boxing o unboxing. Contraste con los genéricos de Java, que son azúcar sintáctica que solo realiza los moldes para usted en el fondo (al menos así fue una vez). El principal problema con los genéricos es que no puede tratar los contenedores genéricos polimórficamente, pero eso está un poco fuera de su tema :-)

No puedo hablar con Mono, pero el uso de una interfaz genérica debería resolver el problema de boxing / unboxing en el tiempo de ejecución de MS.

Dado que está utilizando una versión reciente de mono, 2.0 si puede.

El rendimiento de la interfaz genérica en Mono es muy bueno, junto con el envío regular de la interfaz.

El envío de métodos virtuales genéricos [1] es terrible en todas las versiones lanzadas de mono, ha mejorado en 1.9 miles.

El problema no es tan malo, ya que el problema de rendimiento con los métodos virtuales genéricos se ha solucionado para la próxima versión de mono (2.2), que está programada para finales de este año.

[1] Un método virtual genérico es algo así como:

interfaz pública Foo {

  void Bla<T> (T a, T b);

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top