MemberExpression Dynamic

c# dynamic expression-trees linq


I just know the field name and want to generate a MemberExpression, for example:

public static Expression<Func<TModel, T>> GenerateMemberExpression<TModel, T>(string fieldName)
        PropertyInfo fieldPropertyInfo;

        fieldPropertyInfo = typeof(TModel).GetProperty(fieldName);

        var entityParam = Expression.Parameter(typeof(TModel), "e"); // {e}
        var columnExpr = Expression.MakeMemberAccess(entityParam, fieldPropertyInfo); // {e.fieldName}
        var lambda = Expression.Lambda(columnExpr, entityParam) as Expression<Func<TModel, T>>; // {e => e.column}

        return lambda;

The issue with the aforementioned is that a highly typed field type is required. It is ineffective to enter "object" as the field type. Is it possible to produce this? Even Dynamic LINQ seems to be ineffective.

3/16/2011 6:44:02 AM

Accepted Answer

Your code has a variety of problems, including:

  1. Your method's argument is known asfieldName yet you're just receiving a property in return.
  2. You're using a non-genericExpression.Lambda method for generating the statement that, if the type-argument is present, may choose an unsuitable delegate typeT The type provided to the method differs from the type of the property. Specifically, theas A failed attempt to cast the expression to the method's return type will result innull Use the generic as a fix.Lambda using the proper type-arguments in the method. No casting is necessary.
  3. In the event that the second problem is resolved and a secure reference conversion from the property-type toT but not when more difficult transformations, like boxing or lifting, are necessary. Use the Expression.Convert technique when appropriate.

Here is a modification to your sample that takes these concerns into account:

public static Expression<Func<TModel, T>> GenerateMemberExpression<TModel, T>
   (string propertyName)
    var propertyInfo = typeof(TModel).GetProperty(propertyName);

    var entityParam = Expression.Parameter(typeof(TModel), "e"); 
    Expression columnExpr = Expression.Property(entityParam, propertyInfo);

    if (propertyInfo.PropertyType != typeof(T))
        columnExpr = Expression.Convert(columnExpr, typeof(T));

    return Expression.Lambda<Func<TModel, T>>(columnExpr, entityParam);

The calls listed below will all be successful as a result:

GenerateMemberExpression<FileInfo, string>("Name");
GenerateMemberExpression<string, int>("Length");

// Reference conversion
GenerateMemberExpression<FileInfo, object>("Name");          

//Boxing conversion
GenerateMemberExpression<string, object>("Length");

//Lifted conversion
GenerateMemberExpression<string, int?>("Length");
3/16/2011 6:52:39 AM

Popular Answer

Attempt manually transforming the field value if a "object" is given. For instance:

var columnExpr = Expression.MakeMemberAccess(entityParam, fieldPropertyInfo); // {e.fieldName}
if (T.GetType().Equals(typeof(object)))
    columnExpr = Expression.Convert(columnExpr, typeof(object));

I hope this is helpful.

Related Questions

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow