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?

Didáctica
fuente
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()
});
Mark Byers
fuente
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).

Eric Lippert
fuente
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
JohnD
fuente
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();
Dylan Smith
fuente
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(); 
Matt Dawdy
fuente
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.

Adam Robinson
fuente