2011-11-01 9 views
173

Estoy probando algunos servicios de WCF que envían objetos con Guids de ida y vuelta. En mi código de prueba de una aplicación web, que estoy haciendo las siguientes: GUIDGuid es todo 0 (ceros)?

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

Por alguna razón, la llamada a nuevo GUID() está generando con todo de 0 (ceros) de esta manera:

00000000-0000-0000-0000-000000000000

¿Qué podría estar causando esto?

+8

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. –

+0

Superposición: http://stackoverflow.com/q/7972658/60761 –

+2

Se ha eliminado la parte editada que cambió la pregunta. – Didaxis

Respuesta

332

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

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

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

17

trate de hacer:

Guid = Guid.NewGuid(); 
16

No puedo decirle cuántas veces ha cogido. yo.

Guid myGuid = Guid.NewGuid(); 
54

Tal vez puedas probar:

Guid = Guid.NewGuid(); 

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

Cuando crea un nuevo Guid, lo inicializa a todos los ceros, que es el valor predeterminado para Guid. Es básicamente el mismo que crear una "nueva" int (que es un tipo de valor, pero usted puede hacer esto 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 

comparar 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 
+0

'g1' solo se compilará como campo y no como variable local. Además, los índices en su columna de comentarios no coinciden con la misma línea del código – CodesInChaos

+0

@CodeInChaos: Gracias, corrigió los comentarios. FYI, la línea g1 realmente compila ... – JohnD

+2

Se compilará como está, pero no tiene un valor definido. Si agrega un código que lo lea (antes de escribirlo) ya no compilará. – CodesInChaos

99

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 devuelve la forma cero de ese tipo de valor, cualquiera que sea. Es lógicamente el mismo que default(S).

+1

¿Se compila en la misma IL como 'default (S)' o hay alguna sutileza que me falta? – configurator

+5

@configurator: Sí. 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 * bastante * idénticos. Por ejemplo, 'const int x = new int();' no se supone que sea legal de acuerdo con la especificación, pero 'const int x = default (int);' is; permitimos ambos. –

+0

@configurator: si le interesan los casos de esquina relacionados, tal vez http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx también sea de interesar. – kvb

10

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

Al abordar su edición subsiguiente, necesitará publicar el código para su clase RequestObject. Sospecho que su propiedad guid no está marcada como DataMember, y por lo tanto no se está serializando a través del cable. Como default(Guid) es lo mismo que new Guid() (es decir, todos 0), esto explicaría el comportamiento que estás viendo.