Sind ref und out in C # die gleichen Zeiger in C ++?

8

Ich habe gerade eine Swap-Routine in C # so gemacht:

%Vor%

Es macht dasselbe, was dieser C ++ Code tut:

%Vor%

Also sind die Schlüsselwörter ref und out wie Zeiger für C #, ohne unsafe code zu verwenden?

    
Bob Dylan 22.07.2009, 18:46
quelle

7 Antworten

10

Sie sind begrenzter. Sie können ++ für einen Zeiger sagen, aber nicht für ref oder out .

BEARBEITEN Einige Verwirrung in den Kommentaren, um absolut klar zu sein: Der Punkt hier ist, mit den Fähigkeiten von Zeigern zu vergleichen. Sie können dieselbe Operation nicht als ptr++ für eine ref / out ausführen, d. H. Sie adressieren eine benachbarte Position 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 von -Werten zu vergleichen, nicht mit Zeigern.

Es ist eine sichere Wette, dass sie intern nur Zeiger sind, weil der Stapel nicht verschoben wird und C # sorgfältig organisiert ist, so dass sich ref und out immer auf eine aktive Region des Stapels beziehen.

BEARBEITEN Um noch einmal ganz klar zu sein (wenn es nicht bereits aus dem folgenden Beispiel klar war), ist der Punkt hier nicht, dass ref / out nur Zeigen Sie auf den Stapel. Es ist das wenn es auf den Stack zeigt, wird durch die Sprachregeln garantiert, dass es nicht zu einem ungeordneten Pointer wird. Diese Garantie ist notwendig (und relevant / interessant hier), weil der Stapel Informationen einfach in Übereinstimmung mit Methodenaufruf-Exits verwirft, ohne dass überprüft wird, ob noch Verweiser vorhanden sind.

Umgekehrt, wenn ref / out sich auf Objekte im GC-Heap bezieht, ist es nicht verwunderlich, dass diese Objekte so lange am Leben erhalten werden können, wie es nötig ist: Der GC-Heap ist genau dafür entworfen, Objekte für irgendeinen zu behalten Länge der Zeit, die von ihren Referrern benötigt wird, und bietet 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 sehr eng mit Zeigern verwandt ist. Wenn eine COM-Schnittstelle beispielsweise wie folgt deklariert wird:

%Vor%

Die Interop-Assembly wird daraus folgendes machen:

%Vor%

Und Sie können dies tun, um es aufzurufen (ich glaube, das COM-Interop-Zeug kümmert sich darum, das Array zu fixieren):

%Vor%

Mit anderen Worten: ref auf das erste Byte gibt Ihnen Zugriff auf alles; es ist anscheinend ein Zeiger auf das erste Byte.

    
Daniel Earwicker 22.07.2009, 18:51
quelle
6

Referenzparameter in C # können verwendet werden, um eine Verwendung von Zeigern zu ersetzen, ja. Aber nicht alle.

Eine weitere häufige Verwendung von Zeigern besteht in der Möglichkeit, über ein Array zu iterieren. Out / ref-Parameter können das nicht, also nein, sie sind nicht "die gleichen wie Zeiger".

    
jalf 22.07.2009 18:50
quelle
3

ref und out werden nur zusammen mit Funktionsargumenten verwendet, um anzugeben, dass das Argument als Referenz anstelle von Wert übergeben werden soll. In diesem Sinne, ja, sie sind etwas wie Zeiger in C ++ (eher wie Referenzen tatsächlich). Lesen Sie mehr dazu in diesem Artikel .

    
Saulius Valatka 22.07.2009 18:54
quelle
2

Eigentlich würde ich sie mit C ++ - Verweisen und nicht mit Zeigern vergleichen. Pointers, in C ++ und C, sind ein allgemeineres Konzept und Referenzen werden tun, was Sie wollen.

All dies sind natürlich zweifellos Hinweise unter den Deckblättern.

    
David Thornley 22.07.2009 18:54
quelle
1

Das Schöne an der Verwendung von out ist, dass Ihnen garantiert wird, dass dem Objekt ein Wert zugewiesen wird - andernfalls erhalten Sie einen Kompilierungsfehler.

    
bufferz 22.07.2009 18:53
quelle
1

Während Vergleiche im Auge des Betrachters sind ... sage ich nein. 'ref' ändert die Aufrufkonvention , nicht jedoch den Typ der Parameter. In Ihrem C ++ - Beispiel haben d1 und d2 den Typ int *. In C # sind sie immer noch Int32, sie werden einfach als Referenz und nicht als Wert übergeben.

Übrigens tauscht Ihr C ++ - Code seine Eingaben im herkömmlichen Sinne nicht wirklich aus. Verallgemeinern Sie es so:

%Vor%

... funktioniert nur, wenn alle Typen T Kopierkonstruktoren haben und selbst dann viel ineffizienter sind als das Vertauschen von Zeigern.

    
Richard Berg 22.07.2009 18:58
quelle
1

Die kurze Antwort ist Ja (ähnliche Funktionalität, aber nicht genau der gleiche Mechanismus). Wenn Sie FxCop verwenden, um Ihren Code zu analysieren, führt die Verwendung von out und ref zu einem "Microsoft.Design" -Fehler von "CA1045: DoNotPassTypesByReference".

    
Erich Mirabal 22.07.2009 18:51
quelle

Tags und Links