2009-02-18 18 views
23

¿Hay alguna diferencia entre los dos estados:nueva IntPtr (0) vs. IntPtr.Zero

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

he visto muchos ejemplos que utilizan PInvoke que prefieren la primera sintaxis si el argumento myPtr se envía por ref a la función llamada. Si reemplazaré todos los nuevos IntPtr (0) con IntPtr.Zero en mi aplicación, ¿causará algún daño?

+0

'IntPtr.Zero' es más legible. Creo que cumplirlo será mejor – user

Respuesta

24

IntPtr es un tipo de valor, por lo que a diferencia de String.Empty hay relativamente pocos beneficios en tener la propiedad estática IntPtr.Zero

Tan pronto como se pasa IntPtr.Zero en cualquier lugar que obtendrá una copia, por lo que para la inicialización variables no hace ninguna diferencia:

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 

Hay una excepción, y esa es la comparación:

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

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

Como ya han dicho un par de carteles.

7

Son funcionalmente equivalentes, por lo que no deberían causar ningún problema.

IntPtr.Zero representa el estado predeterminado de la estructura (se declara pero no se utiliza ningún constructor), por lo que el valor predeterminado de intptr (void *) sería nulo. Sin embargo, como (void *) nula y (void *) 0 son equivalentes, IntPtr.Zero == nueva IntPtr (0)

Editar: Mientras que son equivalentes, lo que recomendaría el uso de IntPtr.Zero para las comparaciones desde simplemente es más fácil de leer

+0

Eso es lo que creo ... :) Entonces, ¿por qué hay alrededor de un millón de muestras en la web que usan el nuevo IntPtr (0)? ¿No es mejor usar la versión de variable estática? –

-2

Es sobre todo una materia de encapsulación (y de rendimiento, pero en mucha menor medida). En algún momento en el futuro, Microsoft puede decidir (aunque es muy poco probable) que un valor de puntero unificado sea a partir de ahora igual a 0xDEADBEEF, por lo que el código new IntPtr(0) no será válido.

En lo que a rendimiento se refiere, MSDN dice esto:

Por ejemplo, suponiendo que la variable, ip, es una instancia de IntPtr. Puede determinar si se ha establecido comparándolo con el valor devuelto por un constructor, por ejemplo: "if ip! = New IntPtr (0) ...". Sin embargo, invocar a un constructor para obtener un puntero no identificado es ineficiente. Es mejor codificar "if ip != IntPtr.Zero..." o "if !IntPtr.Zero.Equals(ip)...".

+0

-1: El primer párrafo no es correcto. nuevo IntPtr (0) no crea un IntPtr no inicializado; crea uno que se inicializa explícitamente a cero. Como lo hace IntPtr.Zero. Los dos son absolutamente semánticamente idénticos. –

+0

El punto es que IntPtr.Zero puede cambiarse para que sea igual a algo distinto de cero sin romper ningún código de terceros. –

+0

No, no puede. Es un IntPtr con un valor de cero, como su nombre indica. Desde MSDN: "Un campo de solo lectura que representa un puntero o identificador que se ha inicializado a cero". (http://msdn.microsoft.com/en-us/library/system.intptr.zero.aspx) –

5

El uso de IntPtr.Zero le permitirá evitar una nueva instancia de IntPtr.

de msdn:

Utilice este campo para eficientemente determinar si una instancia de IntPtr se ha establecido en un valor distinto que cero

+0

cierto, pero eso no se aplica a ninguno de los casos que menciona el OP. –

1

¿Qué pasa si pasa IntPtr.Zero por ref y el destinatario intenta modificar la referencia? A partir de ese momento, ¿sería IntPtr.Zero != new IntPtr(0), o el destinatario recibiría algún tipo de excepción al tratar de realizar el cambio?

No estoy seguro de esto, pero parece una explicación razonable.

+0

No se puede pasar un campo de solo lectura como un parámetro de referencia. –

+0

Eso es lo que temía ... Pero creo que eso no sucede. Porque realmente no estoy enviando IntPtr.Zero por ref. Probablemente estoy enviando un boxeo del myPtr. Pero tampoco estoy seguro de eso ... De ahí mi pregunta ... :) –

+1

Si asigna IntPtr.Zero a una variable antes de pasarlo a su otro método, no está pasando IntPtr.Zero sino una copia local (es una estructura). –

0

El JITter puede alinear IntPtr.Zero del mismo modo que en línea IntPtr.Size.