2010-08-31 8 views
7

Tengo una estructura con algunos campos. Uno de los campos es de tipo genérico. El tipo genérico podría ser ya sea un tipo de referencia o un tipo de valor.Forzar un tipo de valor (genérico) para que sea una referencia

Quiero forzar que se guarde como referencia internamente, para evitar que la estructura sea demasiado grande.

struct Foo<T> 
{ 
    T field; // should be a reference 
} 

Sé que podría utilizar object o T[], pero ambos es incómoda. ¿No hay algo así como un tipo de referencia genérico?

struct Foo<T> 
{ 
    Reference<T> field; 
} 

Sí, claro, podría escribir la mía. Pero estoy tratando de evitar que

+0

No entiendo cómo se resuelve el problema. Supongamos que S es un tipo de gran valor. Entonces Foo es * del mismo tamaño * que S. Si el usuario está bien con el rendimiento de S, ¿por qué no se encontrarán también con el rendimiento de Foo ? El boxeo S, ya sea que selecciones un objeto o una clase de boxeo personalizada, usará * más * espacio en general porque tendrás que tener espacio para la instancia de S * y * espacio para el cuadro. Boxing S usará * más * tiempo porque lleva tiempo guardar cajas y unbox S. –

+0

Y mantener S en un tipo de referencia agregará una presión considerable al recolector de basura si hay muchas de ellas. ¿Puede explicar por qué cree que se trata de algún tipo de victoria, porque me parece que es una situación mala, es decir, el costo de perforación de una gran estructura, mucho, mucho peor? –

+0

@Eric: No quiero que la estructura se convierta en grande. las estructuras deben ser pequeñas en el uso de la memoria. Hay otros campos en esta estructura y ya está en el límite superior. Si T fuera un tipo de valor Guid o incluso mayor, la estructura resultante sería grande. –

Respuesta

2

Si está tratando de estar absolutamente seguro de que cualquier Tipo de valor está encuadrado, lo almacena en un campo de objeto y usa una propiedad para aplicar la restricción genérica; es decir:

struct Example<T> 
{ 
    private object obj; 
    public T Obj 
    { 
     get 
     { 
      return (T)obj; 
     } 
     set 
     { 
      this.obj = value; 
     } 
    } 
} 
+0

se debe tener en cuenta, sin embargo, dependiendo de cómo se utiliza esta estructura, que la memoria bruta de la estructura puede diferir en dos valores idénticos, ya que las estructuras no se internan y las cajas tendrán diferentes punteros. el método Equals aún funcionará para la comparación administrada, por lo que esto solo es una preocupación para las transiciones administradas> nativas específicas. – TheXenocide

+0

Pensaba que Tuple era un ValueType, pero aparentemente no lo es, así que recomiendo la respuesta de Thecoop. – TheXenocide

9

Defina T para ser una clase.

struct Foo<T> where T : class 
{ 
    T field; // Now it's a reference type. 
} 
+0

inteligente y rápido ... – Dienekes

+0

no, no quiero forzar que T sea una clase. Cuando T es un tipo de valor, quiero que se almacene como referencia. –

+0

Reformé la pregunta para dejar esto en claro. –

-1

y si usted quiere que sea una instancia:

where T : new() 
+1

Siempre será una instancia o ref nula. utiliza new() si el objeto de tipo T necesita creación de instancias a través del constructor predeterminado de tipo T en tiempo de ejecución. –

3

Puede utilizar Tuple<T1> para mantener la variable de tipo de valor (Tuples son clases en el BCL)

struct Foo<T> 
{ 
    Tuple<T> field; 
} 
Cuestiones relacionadas