c# - How to dynamically create a lambda expression -
let's suppose have following class:
public class show { public string language { get; set; } public string name { get; set; } } based on information, goal create lambda expression this:
g => g.language == lang && g.name == name lang , name local variables add constant values when creating expression.
as can see, compiled function of type func<genre, bool>
to understand more clearly, achieve similar this:
string lang = "en"; string name = "comedy"; genre genre = new genre { language = "en", name = "comedy" }; expression<func<genre, bool>> expression = createexpression(genre, lang, name); // expression = (g => g.language == "en" && g.name == "comedy") i aware of existence of expression trees i'm pretty new topic don't know how start.
can problem solved? how can create such expression dynamically?
public expression<func<tvalue, bool>> createexpression<tvalue, tcompare>(tvalue value, tcompare compare) { var pv = expression.parameter(typeof(tvalue), "data"); var compareprops = typeof(tcompare).getproperties(); // first statement of expression expression exp = expression.constant(true); foreach (var prop in typeof(tvalue).getproperties()) { // check if compare type has same property if (!compareprops.any(i => i.name == prop.name)) continue; // build expression: value.propertya == "a" // "a" come compare.propertya var eq = expression.equal( expression.property(pv, prop.name), expression.constant(compareprops .single(i => i.name == prop.name) .getvalue(compare))); // append first (previous) statement exp = expression.andalso(exp, eq); } return expression.lambda<func<tvalue, bool>>(exp, pv); } usage:
var value = new { lang = "en", name = "comedy"}; // comparevalue should have same property name value, // or expression ignore property var comparevalue = new { lang = "en", name = "comedy", other = "xyz" }; // create expression content // {data => ((true andalso (data.lang == "en")) andalso (data.name == "comedy"))} bool ismatch = createexpression(value, comparevalue).compile()(value); // true
Comments
Post a Comment