vendredi 28 octobre 2016

How to assign a value to a nullable through reflection

How do I set a Nullable<T> value through reflection? I was able to set values that are not Nullable<T> and detect if a type is of type Nullable<T> but I don't find a way how to set this value properly.

This is the current snippet:

public bool SetProperty(string propertyLambdaString, object value)
{
    try
    {
        ParameterExpression paramParty = Expression.Parameter(typeof(TModel), "model");
        MemberExpression property = BuildPropertyExpression(paramParty, propertyLambdaString);
        ParameterExpression paramValue = Expression.Parameter(value.GetType(), "value");

        if (Nullable.GetUnderlyingType(property.Type) != null)
        {
            // TODO: Question: How to assign a value to a nullable? Assign throws exception.
            //Expression assignmentExp = Expression.Assign(property, paramValue);
            //LambdaExpression lambda = Expression.Lambda(
            //  assignmentExp,
            //  new List<ParameterExpression> { paramParty, paramValue });
            //lambda.Compile().DynamicInvoke(this.model, value);

            return false;
        }

        // TODO: Question: How to set a value to null?
        Expression assignmentExp = Expression.Assign(property, paramValue);
        LambdaExpression lambda = Expression.Lambda(
            assignmentExp,
            new List<ParameterExpression> { paramParty, paramValue });
        lambda.Compile().DynamicInvoke(this.model, value);
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        return false;
    }

    return true;
}

private static MemberExpression BuildPropertyExpression(Expression param, string propertyLambdaString)
{
    int firstDelim = propertyLambdaString.IndexOf('.');
    if (firstDelim < 0)
    {
        return Expression.Property(param, propertyLambdaString);
    }

    string head = propertyLambdaString.Substring(0, firstDelim);
    string tail = propertyLambdaString.Substring(firstDelim + 1);
    MemberExpression expr = BuildPropertyExpression(param, head);
    return BuildPropertyExpression(expr, tail);
}





Aucun commentaire:

Enregistrer un commentaire