Guid es todo 0 (ceros)?


241

Estoy probando algunos servicios WCF que envían objetos con guías de un lado a otro. En mi código de prueba de aplicación web, estoy haciendo lo siguiente:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid()
});

Por alguna razón, la llamada a new Guid () está generando Guids con todos los 0 (ceros) como este:

00000000-0000-0000-0000-000000000000

¿Qué podría estar causando esto?


99
Después de su edición, esta es una pregunta completamente nueva. Y se necesita mucha más información para determinar la nueva respuesta.
Scott Rippey el

3
Se eliminó la parte editada que cambió la pregunta.
Didaxis

115
+1 porque he usado esta pregunta para robar una guía en blanco una docena de veces :)
jmosesman

55
@jmosesman, es mejor usar el formularioGuid.Empty
Jonathan Moosekian

44
@ JonathanM En realidad lo estoy usando en un script SQL. Esta publicación solo aparece primero después de la búsqueda.
jmosesman

Respuestas:


428

Use el método estático en Guid.NewGuid()lugar de llamar al constructor predeterminado.

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = Guid.NewGuid()
});

18
+1 para la respuesta correcta, así como un enlace a la documentación adecuada.
ObscureRobot

109

Lecciones para aprender de esto:

1) Guid es un tipo de valor, no un tipo de referencia.

2) Llamar al constructor predeterminado new S()en cualquier tipo de valor siempre le devuelve la forma de cero de ese tipo de valor, sea cual sea. Es lógicamente lo mismo que default(S).


3
¿Se compila en la misma IL default(S)o hay alguna sutileza que me falta?
Configurador el

8
@configurator: lo hace. De hecho, la representación interna del compilador de "default (S)" y "new S ()" es la misma; no los distinguimos internamente, lo que ha llevado a algunos errores desafortunados a lo largo de los años porque de hecho no son del todo idénticos. Por ejemplo, const int x = new int();no se supone que sea legal de acuerdo con la especificación, pero lo const int x = default(int);es; permitimos ambos.
Eric Lippert el

1
@configurator: si está interesado en casos de esquina relacionados, quizás msmvps.com/blogs/jon_skeet/archive/2008/12/10/… también sería de interés.
kvb

56

Intenta esto en su lugar:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid.NewGuid()
});

Esto generará un valor Guid 'real'. Cuando crea un tipo de referencia nuevo, le dará el valor predeterminado (que en este caso es todo ceros para un Guid).

Cuando crea un nuevo Guid, lo inicializará a todos los ceros, que es el valor predeterminado para Guid. Básicamente es lo mismo que crear un int "nuevo" (que es un tipo de valor pero puede hacerlo de todos modos):

Guid g1;                    // g1 is 00000000-0000-0000-0000-000000000000
Guid g2 = new Guid();       // g2 is 00000000-0000-0000-0000-000000000000
Guid g3 = default(Guid);    // g3 is 00000000-0000-0000-0000-000000000000
Guid g4 = Guid.NewGuid();   // g4 is not all zeroes

Compare esto con hacer lo mismo con un int:

int i1;                     // i1 is 0
int i2 = new int();         // i2 is 0
int i3 = default(int);      // i3 is 0

1
g1solo se compilará como campo y no como variable local. También los índices en su columna de comentario no coinciden con la misma línea del código
CodesInChaos

1
@CodeInChaos: Gracias, arreglé los comentarios. Para su información, la línea g1 realmente compila ...
JohnD

3
Se compilará tal cual, pero no tiene un valor definido. Si agrega código que lo lee (antes de escribir), ya no se compilará.
CodesInChaos

1
Bien, buen punto, obtendrá un error si usa una variable no inicializada, por lo que el valor no se puede usar.
JohnD

1
rechazado porque la línea "Guid = Guid.NewGuid ();" puede confundir a los desarrolladores más nuevos. Considere editar algo como "Guid someGuid = Guid.NewGuid ();" como la línea g2;)
daviesdoesit

25

Trata de hacerlo:

Guid foo = Guid.NewGuid();

1
Motivo del voto negativo: "Guid" es un tipo pero se usa como una variable.
daviesdoesit

19

No puedo decirte cuántas veces esto ha atrapado. yo.

Guid myGuid = Guid.NewGuid(); 

11

En el espíritu de ser completo, las respuestas que le indican que use Guid.NewGuid()son correctas.

Al abordar su edición posterior, deberá publicar el código para su RequestObjectclase. Sospecho que su propiedad guid no está marcada como a DataMembery, por lo tanto, no se está serializando por cable. Como default(Guid)es igual a new Guid()(es decir, todos 0), esto explicaría el comportamiento que está viendo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.