È un hack nella JIT, come indicato nella tua citazione. Quando la macchina virtuale rileva che è presente uno, tratta la classe in modo diverso, consentendo di utilizzare un codice più efficiente.
Guardando il codice rilevante nella VM (nota che sto utilizzando una versione più vecchia pubblica qui - non il attuale NET VM):
Una chiamata a una matrice attraverso IList (o IEnumerable o ICollection) deve essere gestito in modo speciale. Queste interfacce sono "magia" (per lo più a causa di working set in questione - sono creati su richiesta internamente anche se semanticamente, queste sono interfacce statiche.)
Gli array sono un po 'di hack in .NET nel primo posto. Quando sono state aggiunte le interfacce generiche, questo ha rappresentato un piccolo problema: ad esempio, int[]
è un Array
, ma è anche un tipo speciale e un array di int; questo consentiva agli array di essere generici prima che fossero aggiunti i tipi generici reali.
Ora, vediamo un esempio concreto. Hai un int[]
e vuoi usarlo in LINQ. Dal momento che int[]
implementa IEnumerable<int>
, ti dà tutta la potenza di LINQ, fuori dalla scatola, e si può scrivere qualcosa del genere:
var positiveNumbers = numbers.Where(i => i > 0);
Dal punto di vista C# 's, non c'è nessun problema. Tuttavia, dal punto della parte interna della macchina virtuale, questo è un grosso problema, perché int[]
non è in realtà implementa IEnumerable<int>
! Anche dopo aver introdotto i generici su .NET (e C#), gli array vengono ancora gestiti alla vecchia maniera.
L'hack deve utilizzare SZArrayHelper
per gestire uno di questi metodi generici. Quindi, ad esempio, chiama GetEnumerator
internamente allo IEnumerable<int>
. La VM rileva che stai cercando di chiamare GetEnumerator
su un array e invece di inviare virtualmente GetEnumerator
nell'istanza dell'array, reindirizza la chiamata a SZArrayHelper.GetEnumerator<int>()
.
Questo è un enorme mod - se si guarda il codice di riferimento per SZArrayHelper
, troverete tonnellate di avvertimenti - per esempio, il metodo GetEnumerator<int>
è un metodo di istanza, ma è this
argomento è in realtà la matrice (ad esempio int[]
), non SZArrayHelper
.
Ma ci permette di trattare le matrici come se si attuino effettivamente tutte quelle interfacce generiche - anche se non :)
Probabilmente a causa 99,9% degli incassi utilizzare un array per lo storage a un certo livello, in modo da 'ragionevole richiedere tale dipendenza. Questo ti sta causando un problema o sei solo curioso? –
@DStandley: Curioso .. ma di nuovo come fa a garantire che YourValueType [] possa essere usato senza jittare? – NullReference
Non si tratta di 'YourValueType []' * stesso *. Si tratta di usarlo quando lanciato nella corrispondente interfaccia generica. 'int []' * non * implementa effettivamente 'IEnumerable .GetEnumerator' anche se appare come se fosse così - l'effettiva implementazione è in quella misteriosa classe' SZArrayHelper'. –
Luaan