Using ToString method at first in Expression Tree

c# expression-trees

Question

I'm new to expression Tree and I need to convert the below lambda to Expression Tree

Data.Where(s => s.Property.ToString().StartsWith("My Search Data"));

However I have done upto

Data.Where(s => s.Property.StartsWith("My Search Data");

Now I Need to use the ToString Method before Using StartsWith.

Below is my sample code.

ParameterExpression e = Expression.Parameter(typeof(T), "e");
PropertyInfo propertyInfo = typeof(T).GetProperty(field);
MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);
ConstantExpression c = Expression.Constant(data, typeof(string));
MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
Expression call = Expression.Call(m, mi, c);
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, e);
query = query.Where(lambda);

Accepted Answer

The ideea is that you have to get "ToString" method from System.Object. Because it is a virtual method, the Runtime can dispatch the call on your real object.

Note: IData is your whatever data that has a property named "Property".

ParameterExpression e = Expression.Parameter(typeof(IData), "e");
PropertyInfo propertyInfo = typeof(IData).GetProperty("Property");
MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);

var toString = typeof (Object).GetMethod("ToString");

ConstantExpression c = Expression.Constant(data, typeof(string));
MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });

var toStringValue = Expression.Call(m, toString);

Expression call = Expression.Call(toStringValue, mi, c);

Expression<Func<IData, bool>> lambda = Expression.Lambda<Func<IData, bool>>(call, e);

Popular Answer

Consider using the overloads that allow you to access members by name instead. It will make this significantly easier to do.

// Data.Where(s => s.Property.ToString().StartsWith("My Search Data"));
var property = "Property";
var filter = "My Search Data";
var param = Expression.Parameter(typeof(T));
var body = Expression.Call(
    Expression.Call(
        Expression.Property(param, property),
        "ToString",
        null
    ),
    "StartsWith",
    null,
    Expression.Constant(filter)
);
var lambda = Expression.Lambda<Func<T, bool>>(body, param);


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why