Sie sind begrenzter. Sie können ++ auf einem Zeiger, aber nicht auf einem ref
oder out
sagen.
EDIT Einige Verwirrung in den Kommentaren, so absolut klar zu sein: Der Punkt hier ist mit den Fähigkeiten von Zeigern zu vergleichen. Sie können nicht die gleiche Operation wie ptr++
an einem ref
/out
ausführen, d. H. Es adressieren einen benachbarten Ort im Speicher. Es ist wahr (aber irrelevant hier), dass Sie das Äquivalent von (*ptr)++
ausführen können, aber das wäre, es mit den Fähigkeiten Werte, nicht Zeiger zu vergleichen.
Es ist eine sichere Wette, dass sie intern sind nur Zeiger, weil der Stapel nicht bewegt bekommen hat und C# organisiert ist sorgfältig, so dass ref
und out
immer zu einem aktiven Bereich des Stapels beziehen.
EDIT Um absolut klar zu sein, wieder (wenn es nicht bereits aus dem Beispiel unten ist), hier der Punkt ist, dass nicht ref
/out
kann nur Punkt auf den Stapel. Es ist das , wenn es auf den Stapel zeigt, ist es durch die Sprachregeln garantiert, nicht zu einem dangling Zeiger zu werden. Diese Garantie ist notwendig (und relevant/interessant hier), da der Stapel Informationen einfach in Übereinstimmung mit Methodenaufruf-Exits verwirft, ohne dass überprüft wird, ob noch Verweiser vorhanden sind.
Umgekehrt, wenn sich ref
/out
auf Objekte im GC-Heap bezieht, ist es nicht verwunderlich, dass diese Objekte so lange am Leben gehalten werden können: Der GC-Heap ist genau dafür ausgelegt, Objekte für beliebig lange Zeit zu halten Sie werden von ihren Empfängern benötigt und bieten Pinning (siehe Beispiel unten), um Situationen zu unterstützen, in denen das Objekt nicht durch GC-Komprimierung verschoben werden darf.
Wenn Sie jemals mit Interop in unsicherem Code spielen, werden Sie feststellen, dass ref
ist sehr eng mit Zeigern verwendet.Zum Beispiel wird, wenn eine COM-Schnittstelle wie folgt erklärt:
HRESULT Write(BYTE *pBuffer, UINT size);
Die Interopassembly es in diese verwandeln:
void Write(ref byte pBuffer, uint size);
Und Sie können dies nennen es tun (ich die COM-Interop Sachen glauben kümmert sich um das Array von Pinning):
byte[] b = new byte[1000];
obj.Write(ref b[0], b.Length);
Mit anderen Worten, wird Sie die ganze es ref
zum ersten Byte zuzugreifen; es ist anscheinend ein Zeiger auf das erste Byte.
Sie können '++' auf ein 'ref' Argument gut, aber es bedeutet nicht das Gleiche. –
Auch "ref" und "out" beziehen sich immer auf eine aktive Region des Stapels "ist einfach völlig falsch. In Ihrem eigenen Beispiel wird ein Verweis auf ein Objekt im GC-Heap erstellt. –