Domanda

Ho un'interfaccia C # con alcuni parametri del metodo dichiarati come tipi object . Tuttavia, il tipo effettivo trasmesso può variare in base alla classe che implementa l'interfaccia:

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

Il problema con MyClass2 è che la conversione di byte [] in e da oggetto è boxe e unboxing , che sono operazioni costose dal punto di vista computazionale che incidono sulle prestazioni.

Risolve questo problema con una interfaccia generica evitando 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...
    }
}

Come viene implementato in .NET vs Mono? Ci saranno conseguenze sulle prestazioni su entrambe le piattaforme?

Grazie!

È stato utile?

Soluzione

Non sono sicuro di come sia implementato in mono, ma le interfacce generiche aiuteranno perché il compilatore crea una nuova funzione del tipo specifico per ogni diverso tipo utilizzato (internamente, ci sono alcuni casi in cui può utilizzare lo stesso funzione generata). Se viene generata una funzione del tipo specifico, non è necessario selezionare / deselezionare il tipo.

Questo è il motivo per cui la libreria Collections.Generic è stata un grande successo in .NET 2.0 perché le raccolte non richiedevano più la boxe e sono diventate significativamente più efficienti.

Altri suggerimenti

Otterrai gli stessi vantaggi in Mono rispetto a .NET.

Si consiglia vivamente di utilizzare Mono 1.9 o Mono 2.0 RCx in generale, poiché il supporto generici è maturato solo con 1.9.

  

Il problema con MyClass2 è che   conversione di byte [] in e da   oggetto è boxe e unboxing, che   sono computazionalmente costosi   operazioni che incidono sulle prestazioni.

Non vi sono boxe coinvolti con tipi di array, nemmeno uno con elementi di tipo valore. Un array è un tipo di riferimento.

L'overhead su (byte []) arg è minimo nella migliore delle ipotesi.

Sì, in .Net (MS non è sicuro dei mono) i generici sono implementati in fase di compilazione, quindi non c'è alcuna boxe o unboxing in corso. Contrariamente ai generici java che sono zucchero sintattico che esegue semplicemente i cast per te in background (almeno così è stato una volta). Il problema principale con i generici è che non puoi trattare polimorficamente i contenitori generici, ma questo è un po 'fuori tema :-)

Non riesco a parlare con Mono, ma usando un'interfaccia generica dovrei risolvere il problema di boxing / unboxing in runtime MS.

Dato che stai usando una versione recente di mono, 2.0 se puoi.

Le prestazioni dell'interfaccia generica su Mono sono molto buone, in coppia con l'invio regolare dell'interfaccia.

L'invio di metodi virtuali generici [1] è terribile su tutte le versioni di mono rilasciate, è migliorato in 1.9 tu.

Il problema non è così grave in quanto il problema delle prestazioni con i metodi virtuali generici è stato risolto per la prossima versione di mono (2.2), che è prevista per la fine di quest'anno.

[1] Un metodo virtuale generico è simile a:

interfaccia pubblica Foo {

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

}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top