2009-11-10 21 views
22

¿Hay algún uso práctico de la estructura TypedReference que realmente usaría en código real?Usos prácticos de TypedReference

EDITAR: El marco .Net los utiliza en sobrecargas de Console.WriteLine y String.Concat que construyen una matriz desde un parámetro de __arglist y pasarlo a la sobrecarga normal de params. ¿Por qué existen estas sobrecargas?

+1

¿Por qué no es constructivo? : o – nawfal

+1

También vea http://stackoverflow.com/questions/4764573/why-is-typedreference-behind-the-scenes-its-so-fast-and-safe-almost-magical – nawfal

+0

También puede usarlo para aprobar apilar la ubicación/referencia de variable "alrededor" (por ejemplo, a otro hilo o devolverlo del método). Requiere código inseguro y "copiar" TypedReference como dos IntPtr. –

Respuesta

17

¿Hay algún uso práctico de la estructura TypedReference que realmente usaría en código real?

Sí. Los usaría si necesitara interoperabilidad con los métodos variadic de estilo C.

¿Por qué existen estas sobrecargas?

Existen para la interoperabilidad con los llamadores que les gusta usar métodos variadic de estilo C.

+1

+1 por no cerrar de golpe los bits varidiac de estilo C :) Y espero que tengas plantillas variadas (no genéricas) de 5.0. –

10

Parece ser una pregunta muy antigua, pero me gustaría añadir un caso de uso más: cuando tiene una estructura y desea establecer su variable a través de la reflexión, siempre operaría en el valor encuadrado y nunca cambiar el original Esto es inútil:

TestFields fields = new TestFields { MaxValue = 1234 }; 
FieldInfo info = typeof(TestFields).GetField("MaxValue"); 
info.SetValue(fields, 4096); 

// result: fields.MaxValue is still 1234!! 

Esto se puede remediar con el boxeo implícito, pero luego se pierde la seguridad del tipo. En su lugar, puede solucionar esto con un TypedParameter:

TestFields fields = new TestFields { MaxValue = 1234 }; 
FieldInfo info = fields.GetType().GetField("MaxValue"); 

TypedReference reference = __makeref(fields); 
info.SetValueDirect(reference, 4096); 

// result: fields.MaxValue is now indeed 4096!! 
+0

No sé si llamaría esto un problema específico de Reflexión. 'SetValue' toma un objeto como entrada, por lo que cualquier tipo de valor se insertará para coincidir con la firma del método. –

+0

@BrianRasmussen: afaik, este comportamiento específico de la reflexión proviene de Reflection anterior a los genéricos, de lo contrario, el boxeo no sería necesario. En los tipos de valores (pre) enmarcados y las referencias, este problema no aparece. – Abel

+0

Mi punto era que cualquier método que tome 'object' como entrada (que la primera sobrecarga de' SetValue' en su ejemplo) forzará que los valores sean encuadrados. Así es como el sistema de tipo unificado maneja los valores. Eso no es específico de Reflection. –

Cuestiones relacionadas