es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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?

Tags:  ,

Answer

  1. Avatar for davy.ai

    El problema con la implementación actual del método IsValid() es que la instancia de AnalyzedParameter que se recupera de la propiedad se convierte en AnalyzedParameter<object>, lo que causa una InvalidCastException. Esto se debe a que el argumento de tipo T de AnalyzedParameter<t> no siempre puede ser object.

    Para solucionar este problema, el argumento de tipo T de AnalyzedParameter<t> debe recuperarse de la propiedad y usarse para crear una instancia de AnalyzedParameter<t> correctamente tipada. Esto se puede lograr utilizando los métodos Type.MakeGenericType() y Activator.CreateInstance().

    Aquí está la implementación actualizada del método IsValid():

    public bool IsValid()
    {
        var props = GetType().GetProperties().Where(prop => prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(AnalyzedParameter<>));
        var valid = props.All(p =>
        {
            var analyzedParameterType = p.PropertyType;
            var typeArgument = analyzedParameterType.GetGenericArguments()[0];
            var analyzedParameterInstance = p.GetValue(this);
            var typedAnalyzedParameterInstance = Activator.CreateInstance(analyzedParameterType.MakeGenericType(typeArgument), analyzedParameterInstance);
            return (bool)typedAnalyzedParameterInstance.GetType().GetProperty("Valid").GetValue(typedAnalyzedParameterInstance);
        });
    
        return valid;
    }
    

    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 es AnalyzedParameter<t>.
    • analyzedParameterType.GetGenericArguments()[0] se utiliza para recuperar el argumento de tipo T.
    • Activator.CreateInstance(analyzedParameterType.MakeGenericType(typeArgument), analyzedParameterInstance) se utiliza para crear una instancia de AnalyzedParameter<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 propiedad Valid de la instancia de AnalyzedParameter<t> correctamente tipada.

    Con estos cambios realizados, el método IsValid() debería ahora funcionar según lo esperado.

Comments are closed.