¿Cómo utilizo la reflexión para leer propiedades con el mismo tipo genérico pero diferentes argumentos genéricos?
Bueno, siempre puedo codificar en duro la comprobación de propiedades para resolver mi caso, pero quiero hacerlo usando reflexión.
Mi tipo genérico:
public class AnalyzedParameter<t>
{
public T Value { get; set; }
public bool Valid { get; set; }
}
Mi clase:
public class Foo
{
public AnalyzedParameter<int> A { get; set; }
public AnalyzedParameter<string> B { get; set; }
}
Necesito verificar cada propiedad que tenga el tipo AnalyzedParameter
mediante la comprobación de la propiedad Valid
.
Entonces, mi método debe ser así:
public bool IsValid()
{
var props = GetType().GetProperties().Where(prop => prop.PropertyType == typeof(AnalyzedParameter<>));
var valid = props.All(p => ((AnalyzedParameter<object>) p.GetValue(this)).Valid);
return valid;
}
Pero no funciona. ¿Algún idea?
davy.ai
El problema con la implementación actual del método
IsValid()
es que la instancia deAnalyzedParameter
que se recupera de la propiedad se convierte enAnalyzedParameter<object>
, lo que causa unaInvalidCastException
. Esto se debe a que el argumento de tipoT
deAnalyzedParameter<t>
no siempre puede serobject
.Para solucionar este problema, el argumento de tipo
T
deAnalyzedParameter<t>
debe recuperarse de la propiedad y usarse para crear una instancia deAnalyzedParameter<t>
correctamente tipada. Esto se puede lograr utilizando los métodosType.MakeGenericType()
yActivator.CreateInstance()
.Aquí está la implementación actualizada del método
IsValid()
:Para explicar los cambios realizados:
prop.PropertyType.IsGenericType
se utiliza para comprobar si el tipo de propiedad es un tipo genérico.prop.PropertyType.GetGenericTypeDefinition() == typeof(AnalyzedParameter<>)
se utiliza para comprobar si el tipo genérico esAnalyzedParameter<t>
.analyzedParameterType.GetGenericArguments()[0]
se utiliza para recuperar el argumento de tipoT
.Activator.CreateInstance(analyzedParameterType.MakeGenericType(typeArgument), analyzedParameterInstance)
se utiliza para crear una instancia deAnalyzedParameter<t>
correctamente tipada utilizando el argumento de tipo recuperado y la instancia recuperada de la propiedad.(bool)typedAnalyzedParameterInstance.GetType().GetProperty("Valid").GetValue(typedAnalyzedParameterInstance)
se utiliza para recuperar el valor de la propiedadValid
de la instancia deAnalyzedParameter<t>
correctamente tipada.Con estos cambios realizados, el método
IsValid()
debería ahora funcionar según lo esperado.