Pergunta

Eu tenho uma interface C # com certos parâmetros do método declarados como tipos object. No entanto, o tipo real passado ao redor pode ser diferente, dependendo da classe que implementa a interface:

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

O problema com MinhaClasse2 é que a conversão de byte[] de e para object é boxe e unboxing, que são computacionalmente dispendiosas operações que afetam o desempenho.

Será que a solução deste problema com um interface genérica evitar boxe / 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...
    }
}

Como isso é implementado em .NET vs Mono? Haverá implicações de desempenho em qualquer plataforma?

Obrigado!

Foi útil?

Solução

Eu não sei como ele é implementado em mono, mas interfaces genéricas vai ajudar porque o compilador cria uma nova função do tipo específico para cada tipo diferente utilizado (internamente, existem alguns casos em que pode utilizar o mesmo função gerado). Se uma função do tipo específico é gerado, não há necessidade de caixa / unbox do tipo.

É por isso que a biblioteca Collections.Generic foi um grande sucesso no .NET 2.0, porque coleções que já não necessita de boxe e se tornou significativamente mais eficiente.

Outras dicas

Você vai obter os mesmos benefícios em Mono que você faz em .NET.

Recomendamos que você use Mono 1.9 ou Mono 2.0 RCx em geral, como os genéricos suportar apenas o amadureceu com 1,9.

O problema com MinhaClasse2 é que o conversão de byte [] para e a partir de objeto é boxing e unboxing, que são computacionalmente caro operações afetar o desempenho.

Não há boxe envolvido com tipos de matriz, mesmo um com elementos do tipo valor. Um array é um tipo de referência.

A sobrecarga sobre (byte []) arg é mínima na melhor das hipóteses.

Sim, em .Net (MS não tem certeza sobre mono) genéricos são implementados em tempo de compilação para que não haja boxe ou unboxing acontecendo em tudo. Contraste com os genéricos Java que são açúcar sintático que apenas executar os moldes para você em segundo plano (pelo menos era dessa maneira uma vez). O principal problema com os genéricos é que você pode não tratar recipientes genéricos polimorficamente, mas isso é um pouco fora de seu tópico: -)

Eu não posso falar para Mono, mas usando uma interface genérica deve resolver o boxe emissão / unboxing no tempo de execução MS.

Dado que você está usando uma versão recente do mono, 2.0, se puder.

desempenho interface genérica sobre Mono é muito bom, em par com expedição de interface regular.

Envio dos métodos virtuais genéricos [1] é terrível em todas as versões lançadas do mono, melhorou em 1,9 mil.

O problema não é tão ruim quanto o problema de desempenho com métodos virtuais genéricos foi corrigido para o próximo lançamento de mono (2,2), que está programado para o final deste ano.

[1] Um método virtual genérico é algo como:

interface pública Foo {

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

}

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top