2009-02-18 9 views
23

C'è qualche differenza tra le due affermazioni:nuova IntPtr (0) vs. IntPtr.Zero

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

Ho visto molti esempi che utilizzano PInvoke che preferiscono la prima sintassi se l'argomento myPtr viene inviato da ref alla funzione chiamata. Se sostituirò tutto il nuovo IntPtr (0) con IntPtr.Zero nella mia applicazione, causerà danni?

+0

'IntPtr.Zero' è più leggibile. Penso che attenersi sarà meglio – user

risposta

24

IntPtr è un tipo di valore, così diverso String.Empty c'è relativamente poco vantaggio di avere la proprietà statica IntPtr.Zero

Non appena si passa IntPtr.Zero ovunque si otterrà una copia, così per l'inizializzazione variabile non fa differenza:

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 

C'è una sola eccezione, e questo è il confronto:

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

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

Come hanno già detto un paio di poster.

7

Sono funzionalmente equivalenti, quindi non dovrebbe causare problemi.

IntPtr.Zero rappresenta lo stato predefinito della struttura (viene dichiarato ma non viene utilizzato alcun costruttore), pertanto il valore predefinito di intptr (void *) sarebbe nullo. Tuttavia, come (void *) nullo e (void *) 0 sono equivalenti, IntPtr.Zero == nuova IntPtr (0)

Edit: Mentre sono equivalenti, mi faccio consigliare utilizzando IntPtr.Zero per i confronti in quanto è semplicemente più facile da leggere.

+0

Questo è quello che penso anch'io ... :) Quindi perché ci sono circa un milione di campioni sul web che usano il nuovo IntPtr (0)? Non è meglio usare la versione variabile statica? –

-2

Si tratta principalmente di un incapsulamento della materia (e di prestazioni, ma in misura molto minore). A un certo momento, in futuro, Microsoft potrebbe decidere (anche se è molto improbabile) che un valore di puntatore unitario diventerà d'ora in poi uguale a 0xDEADBEEF, rendendo quindi non valido il codice new IntPtr(0).

quanto riguarda le prestazioni è interessato, MSDN dice questo:

Ad esempio, assumere la variabile, ip, è un esempio di IntPtr. È possibile determinare se è stato impostato confrontandolo con il valore restituito da un costruttore, ad esempio: "if ip! = New IntPtr (0) ...". Tuttavia, invocare un costruttore per ottenere un puntatore non personalizzato è inefficiente. È meglio codificare "if ip != IntPtr.Zero..." o "if !IntPtr.Zero.Equals(ip)...".

+0

-1: il primo paragrafo non è corretto. new IntPtr (0) non crea un IntPtr non inizializzato; crea uno che è esplicitamente inizializzato a zero. Come fa IntPtr.Zero. I due sono assolutamente semanticamente identici. –

+0

Il punto è che IntPtr.Zero può potenzialmente essere modificato per essere uguale a qualcosa diverso da zero senza rompere alcun codice di terze parti. –

+0

No, non può. È un IntPtr con un valore pari a zero, come indica il nome. Da MSDN: "Un campo di sola lettura che rappresenta un puntatore o un handle che è stato inizializzato a zero." (http://msdn.microsoft.com/en-us/library/system.intptr.zero.aspx) –

5

L'utilizzo di IntPtr.Zero consente di evitare una nuova istanza di IntPtr.

da msdn:

Utilizzare questo campo per determinare in modo efficiente se un'istanza di IntPtr è stato impostato su un valore diverso da zero

+0

vero, ma in questo non si applica a nessuno dei casi menzionati dall'OP. –

1

Che cosa succede se si passa IntPtr.Zero da ref e il destinatario prova a modificare il riferimento? Da quel momento in avanti, sarebbe IntPtr.Zero != new IntPtr(0), o il destinatario riceverà qualche tipo di eccezione nel tentativo di apportare la modifica?

Non ne sono sicuro, ma sembra una spiegazione ragionevole.

+0

Non è possibile passare un campo di sola lettura come parametro ref. –

+0

Questo è quello di cui avevo paura ... Ma penso che non succeda. Perché in realtà non sto inviando IntPtr.Zero di riferimento. Probabilmente sto inviando una boxe di myPtr. Ma non ne sono nemmeno sicuro ... Quindi la mia domanda ... :) –

+1

Se assegni IntPtr.Zero a una variabile prima di passarla all'altro metodo, non stai passando a IntPtr.Zero ma a una copia locale (è una struttura). –

0

JITter può incorporare IntPtr.Zero nello stesso modo in IntPtr.Size.