2009-02-18 6 views
23

Gibt es einen Unterschied zwischen den beiden Aussagen:neue IntPtr (0) vs. IntPtr.Zero

IntPtr myPtr = new IntPtr(0); 
IntPtr myPtr2 = IntPtr.Zero; 

ich viele Proben gesehen haben, die PInvoke verwenden, die die erste Syntax bevorzugen, wenn die myPtr Argument ref gesendet wird zur aufgerufenen Funktion. Wenn ich alle neuen IntPtr (0) durch IntPtr.Zero in meiner Anwendung ersetzen werde, wird es Schaden verursachen?

+0

'IntPtr.Zero' ist besser lesbar. Ich denke, bleib dran, es wird besser sein – user

Antwort

24

IntPtr ein Werttyp ist, so anders als String.Empty dort mit der statischen Eigenschaft IntPtr.Zero

Sobald Sie IntPtr.Zero überall Sie eine Kopie erhalten, relativ wenig Nutzen ist passieren so für variable Initialisierung macht es keinen Unterschied:

IntPtr myPtr = new IntPtr(0); 
IntPtr myPtr2 = IntPtr.Zero; 

//using myPtr or myPtr2 makes no difference 
//you can pass myPtr2 by ref, it's now a copy 

Es gibt eine Ausnahme, und das ist Vergleich:

if(myPtr != new IntPtr(0)) { 
    //new pointer initialised to check 
} 

if(myPtr != IntPtr.Zero) { 
    //no new pointer needed 
} 

Wie ein paar Plakate schon gesagt haben.

7

Sie sind funktional gleichwertig, so sollte es keine Probleme verursachen.

IntPtr.Zero stellt den Standardstatus der Struktur dar (es wird deklariert, aber es wird kein Konstruktor verwendet), daher wäre der Standardwert von intptr (void *) null. IntPtr.Zero jedoch als (void *) null und (void *) 0 äquivalent sind, == neue IntPtr (0)

Edit: Während sie gleichwertig sind, ich empfehlen, da die Verwendung IntPtr.Zero für Vergleiche es ist einfacher zu lesen.

+0

Das ist, was ich denke auch ... :) Warum gibt es etwa eine Million Proben im Internet, die das neue IntPtr (0) verwenden? Ist es nicht besser, die Version der statischen Variablen zu verwenden? –

-2

Es ist meist eine Angelegenheit Einkapselung (und der Leistung, aber zu einem viel geringeren Ausmaß). Zu einem bestimmten Zeitpunkt in der Zukunft könnte Microsoft entscheiden (obwohl es sehr unwahrscheinlich ist), dass ein unitialisierter Zeigerwert von nun an gleich 0xDEADBEEF ist, wodurch alle new IntPtr(0)-Codes ungültig werden.

Was Leistung angeht, so sagt MSDN dies:

zum Beispiel angenommen, die Variable, ip, eine Instanz von IntPtr ist. Sie können feststellen, ob es festgelegt wurde, indem Sie es mit dem Wert vergleichen, der von einem Konstruktor zurückgegeben wird, zum Beispiel: "if ip! = New IntPtr (0) ...". Das Aufrufen eines Konstruktors zum Abrufen eines unintialisierten Zeigers ist jedoch ineffizient. Es ist besser, entweder "if ip != IntPtr.Zero..." oder "if !IntPtr.Zero.Equals(ip)..." zu programmieren.

+0

-1: Der erste Absatz ist nicht korrekt. new IntPtr (0) erstellt kein nicht initialisiertes IntPtr; es erstellt eine, die explizit auf Null initialisiert wird. Genau wie IntPtr.Zero. Die beiden sind absolut semantisch identisch. –

+0

Der Punkt ist, dass IntPtr.Zero möglicherweise geändert werden kann, um etwas anderes als Null zu sein, ohne Code von Drittanbietern zu brechen. –

+0

Nein, kann es nicht. Es ist ein IntPtr mit einem Wert von Null, wie der Name angibt. Von MSDN: "Ein schreibgeschütztes Feld, das einen Zeiger oder ein Handle darstellt, das auf Null initialisiert wurde." (http://msdn.microsoft.com/en-us/library/system.intptr.zero.aspx) –

5

Die Verwendung von IntPtr.Zero ermöglicht es Ihnen, eine neue Instanz von IntPtr zu vermeiden.

von msdn:

Verwenden Sie dieses Feld, um effizient zu bestimmen, ob eine Instanz von IntPtr hat auf einen anderen Wert gesetzt worden ist als Null

+0

wahr, aber das gilt nicht für jeden der Fälle, die das OP erwähnt. –

1

Was ist, wenn Sie mit dem Schiedsrichter übergeben IntPtr.Zero geschieht , und der Empfänger versucht, die Referenz zu ändern? Von diesem Moment an, würde IntPtr.Zero != new IntPtr(0), oder würde der Empfänger eine Art von Ausnahme erhalten, wenn Sie versuchen, die Änderung zu machen?

Ich bin mir nicht sicher, aber es scheint wie eine vernünftige Erklärung.

+0

Sie können ein schreibgeschütztes Feld nicht als Ref-Parameter übergeben. –

+0

Das war, wovor ich Angst hatte ... Aber ich denke, dass es nicht passiert. Weil ich IntPtr.Zero nicht wirklich per ref. Ich schicke wahrscheinlich ein Boxen des myPtr. Aber ich bin mir auch nicht wirklich sicher ... Daher meine Frage ... :) –

+1

Wenn Sie IntPtr.Zero einer Variablen zuweisen, bevor Sie sie an Ihre andere Methode übergeben, übergeben Sie IntPtr.Zero nicht, sondern eine lokale Kopie (Es ist eine Struktur). –

0

Der JITter kann IntPtr.Zero auf die gleiche Weise wie Inlines IntPtr.Size inline.