Es ist ein Hack in der JIT, wie in Ihrem Zitat erwähnt. Wenn die VM feststellt, dass es eine TypeDependency
unter SZArrayHelper
gibt, behandelt sie die Klasse anders, so dass effizienterer Code verwendet werden kann.
an der entsprechenden Code-Suche in der VM (Anmerkung, die ich verwende eine ältere, öffentlich zugängliche Version hier - nicht die tatsächliche .NET VM):
einen Aufruf an ein Array durch IList (oder IEnumerable oder ICollection) muss speziell behandelt werden. Diese Schnittstellen sind „Magie“ (vor allem aufgrund Workingset betroffen - sie auf Verlangen werden intern obwohl semantisch, sind diese statischen Schnittstellen.)
Arrays sind ein bisschen wie ein Hack in .NET in der erster Platz. Wenn die generischen Schnittstellen hinzugefügt wurden, stellte dies ein kleines Problem dar - zum Beispiel int[]
ist ein Array
, aber es ist auch ein spezieller Typ und ein Array von int; Dies erlaubte Arrays, generisch zu sein, bevor echte generische Typen hinzugefügt wurden.
Jetzt sehen wir uns ein konkretes Beispiel an. Sie haben eine int[]
, und Sie möchten es in LINQ verwenden. Da int[]
IEnumerable<int>
implementiert, es gibt Ihnen die volle Leistung von LINQ aus der Box, und Sie können so etwas schreiben:
var positiveNumbers = numbers.Where(i => i > 0);
Von C# 's Sicht, gibt es kein Problem. Von dem Punkt der Interna der VM ist diese jedoch ein großes Problem, weil int[]
nicht tatsächlich implementieren IEnumerable<int>
! Auch nach der Einführung von Generics in .NET (und C#) werden Arrays immer noch auf die alte Art und Weise behandelt.
Der Hack soll SZArrayHelper
verwenden, um mit all diesen generischen Methoden umzugehen. So ruft zum Beispiel Where
GetEnumerator
intern auf der IEnumerable<int>
. Die VM stellt fest, dass Sie versuchen, GetEnumerator
in einem Array aufzurufen, und anstatt GetEnumerator
auf der Array-Instanz virtuell zu verteilen, leitet sie den Aufruf an SZArrayHelper.GetEnumerator<int>()
um.
Dies ist ein riesige Hack - wenn Sie für SZArrayHelper
auf dem Referenzcode anschauen, werden Sie Tonnen von Warnungen finden - zum Beispiel die GetEnumerator<int>
Methode ist eine Instanzmethode, aber es ist this
Argument ist eigentlich die Array (z. B. int[]
), nicht SZArrayHelper
.
Aber es erlaubt uns Arrays zu behandeln, als ob sie tatsächlich alle jene generische Schnittstellen umgesetzt haben - obwohl sie
Wahrscheinlich nicht tun :) da 99,9% der Sammlungen eine Anordnung zur Speicherung auf einer bestimmten Ebene zu verwenden, so dass es "vernünftig, diese Abhängigkeit zu verlangen. Ist das ein Problem oder bist du nur neugierig? –
@DStandley: Neugierig .. aber wieder wie stellt es YourValueType [] kann ohne jitting verwendet werden.? – NullReference
Es geht nicht wirklich um 'YourValueType []' * selbst *. Es geht darum, es zu verwenden, wenn es in die entsprechende generische Schnittstelle umgewandelt wird. 'int []' * * implementiert * IEnumerable nicht wirklich .GetEnumerator', obwohl es so erscheint, als ob es tat - die tatsächliche Implementierung ist in dieser mysteriösen 'SZArrayHelper' Klasse. –
Luaan