Di solito, il trattamento di una struct S
come interfaccia I
attiverà il boxing automatico della struttura, che può avere un impatto sulle prestazioni se eseguito spesso. Tuttavia, se scrivo un metodo generico utilizzando un parametro di tipo T : I
e lo chiamo con un S
, il compilatore non tralascia il boxing, poiché conosce il tipo S
e non deve utilizzare l'interfaccia?I generici C# impediscono l'autoboxing delle strutture in questo caso?
Questo codice mostra il mio punto:
interface I{
void foo();
}
struct S : I {
public void foo() { /* do something */ }
}
class Y {
void doFoo(I i){
i.foo();
}
void doFooGeneric<T>(T t) where T : I {
t.foo(); // <--- Will an S be boxed here??
}
public static void Main(string[] args){
S x;
doFoo(x); // x is boxed
doFooGeneric(x); // x is not boxed, at least not here, right?
}
}
Il metodo doFoo
chiama foo()
su un oggetto di tipo I
, così una volta la chiamiamo con un S
, che S
otterrà in scatola. Il metodo doFooGeneric
fa la stessa cosa. Tuttavia, una volta che lo chiamiamo con un S
, non potrebbe essere richiesto alcun autoboxing, dal momento che il runtime sa come chiamare foo()
su un S
. Ma sarà fatto? O il runtime ciecamente boxing S
a un I
per chiamare il metodo di interfaccia?
Prova ad aggiungere il vincolo 'struct' - vale a dire' vuoto doFooGeneric (T t) dove T: struct, I { ' –
AlexFoxGill
FWIW, utilizzando la funzione di' IsBoxed' da [questa risposta] (http://stackoverflow.com/a/5807132/791010) dice che non è in scatola. Non conosco i dettagli del perché però. –
Correlato se non duplicato: http://stackoverflow.com/questions/3032750/struct-interfaces-and-boxing e appositamente [questa risposta] (http://stackoverflow.com/a/3033357/961113) di Marc Gravell – Habib