2008-11-07 12 views
60

Tengo una clase que almacena un valor serializado y un tipo. Quiero tener una propiedad/método de devolver el valor ya fundido:Haciendo una propiedad genérica

public String Value { get; set; } 

public Type TheType { get; set; } 

public typeof(TheType) CastedValue { get { return Convert.ChangeType(Value, typeof(_Type)); } 

Es esto posible en C#?

+4

Las propiedades genéricas serían agradables; Creo que 'var val = obj.Prop ' es más sucinto para una búsqueda basada en tipos que 'obj.Prop [typeof (Type)]' or 'obj.GetProp ()'. – Dan

Respuesta

93

Es posible si la clase que contiene la propiedad es genérico, y declarar el establecimiento en el parámetro genérico:

class Foo<TValue> { 
    public string Value { get; set; } 
    public TValue TypedValue { 
     get { 
      return (TValue)Convert.ChangeType(Value, typeof(TValue)); 
     } 
    } 
} 

Una alternativa sería utilizar un método genérico en lugar:

class Foo { 
    public string Value { get; set; } 
    public Type TheType { get; set; } 

    public T CastValue<T>() { 
     return (T)Convert.ChangeType(Value, typeof(T)); 
    } 
} 

También puede usar las clases System.ComponentModel.TypeConverter para convertir, ya que permiten que una clase defina su propio convertidor.

Editar: tenga en cuenta que cuando se llama al método genérico, debe especificar el parámetro de tipo genérico, ya que el compilador no tiene forma de inferir que:

Foo foo = new Foo(); 
foo.Value = "100"; 
foo.Type = typeof(int); 

int c = foo.CastValue<int>(); 

Usted tiene que saber el tipo en tiempo de compilación . Si no conoce el tipo en tiempo de compilación, entonces debe ser almacenarla en un object, en cuyo caso se puede agregar la siguiente propiedad a la clase Foo:

public object ConvertedValue { 
    get { 
     return Convert.ChangeType(Value, Type); 
    } 
} 
+0

En el segundo ejemplo de la clase 'Foo, estoy desconcertado: una propiedad pública' theType se declara: "public Type TheType {get; set;}" pero parece que no se usa en el código. gracias, – BillW

+0

La propiedad estaba en el ejemplo original. Acabo de dejarlo en. – Brannon

+0

Cuando intento la solución de Brannons obtengo un error de tiempo de ejecución que dice que el objeto que estoy lanzando debe implementar IConvertible. He hecho algo mal porque esto parece ser un factor decisivo a menos que realice una clase donde tengo la fuente disponible. – Keith

3

No creo que el ejemplo 'He dado aquí es posible. El tipo de CastedValue debe definirse en tiempo de compilación, lo que significa que no puede depender de un valor de tiempo de ejecución (el valor de la propiedad TheType).

EDITAR: La solución de Brannon tiene algunas buenas ideas sobre cómo manejar esto utilizando una función genérica en lugar de una propiedad.

52

Las propiedades, eventos, constructores, etc. no pueden ser genéricos; solo los métodos y tipos pueden ser genéricos. La mayoría de las veces eso no es un problema, pero estoy de acuerdo en que a veces es un problema. La respuesta de Brannon da dos soluciones razonables.

Cuestiones relacionadas