C# Reflection Expression Linq












3















I'm having some problems with C# dynamic generated lambda expressions.



Considering the following scenario:



public class Person {
public long Id { get; set; }
public string Name { get; set; }
}

List<Person> persons = new List<Person> () {
new Person { Id = 1, Name = "Foo" },
new Person { Id = 2, Name = "Bar" },
new Person { Id = 3, Name = "Baz" },
new Person { Id = 4, Name = null },
};


Now, doing the follow code



ParameterExpression param = Expression.Parameter(typeof(Person), "arg");
Expression prop = Expression.Property(param, "Name");
Expression value = Expression.Constant("bar");
Type type = prop.Type;

MethodInfo toLower = typeof(String).GetMethod("ToLower", Type.EmptyTypes);
Expression expLower = Expression.Call(prop, toLower);

Expression clausule = Expression.Call(expLower, type.GetMethod("Contains", new { type }), value);
Expression notNull = Expression.NotEqual(prop, Expression.Constant(null));

clausule = Expression.And(notNull, clausule);

var exp = Expression.Lambda<Func<T, bool>>(clausule, param);


The above code generate the following exp.



//arg => ((arg.Name != null) And (arg.Name.ToLower().Contains("bar")))


Now, trying to apply that to my list.



The filter below works



var filteredListThatWorks = persons.Where(arg => arg.Name != null && arg.Name.ToLower().Contains("bar")).ToList();


The one below throws exception of Null object ( because of Id 4 name)



var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();


The same expression, when generated by lambda, throws exp, when manually inputed, works.
Anyone knows a way to solve that ?



Br,










share|improve this question


















  • 1





    also keep in mind - when you use var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();, that is being compiled to a delegate, not an expression tree; if you want truly equivalent code, you should perhaps use persons.AsQueryable().Where(...), which forces it to use the expression-tree API

    – Marc Gravell
    Nov 23 '18 at 10:49
















3















I'm having some problems with C# dynamic generated lambda expressions.



Considering the following scenario:



public class Person {
public long Id { get; set; }
public string Name { get; set; }
}

List<Person> persons = new List<Person> () {
new Person { Id = 1, Name = "Foo" },
new Person { Id = 2, Name = "Bar" },
new Person { Id = 3, Name = "Baz" },
new Person { Id = 4, Name = null },
};


Now, doing the follow code



ParameterExpression param = Expression.Parameter(typeof(Person), "arg");
Expression prop = Expression.Property(param, "Name");
Expression value = Expression.Constant("bar");
Type type = prop.Type;

MethodInfo toLower = typeof(String).GetMethod("ToLower", Type.EmptyTypes);
Expression expLower = Expression.Call(prop, toLower);

Expression clausule = Expression.Call(expLower, type.GetMethod("Contains", new { type }), value);
Expression notNull = Expression.NotEqual(prop, Expression.Constant(null));

clausule = Expression.And(notNull, clausule);

var exp = Expression.Lambda<Func<T, bool>>(clausule, param);


The above code generate the following exp.



//arg => ((arg.Name != null) And (arg.Name.ToLower().Contains("bar")))


Now, trying to apply that to my list.



The filter below works



var filteredListThatWorks = persons.Where(arg => arg.Name != null && arg.Name.ToLower().Contains("bar")).ToList();


The one below throws exception of Null object ( because of Id 4 name)



var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();


The same expression, when generated by lambda, throws exp, when manually inputed, works.
Anyone knows a way to solve that ?



Br,










share|improve this question


















  • 1





    also keep in mind - when you use var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();, that is being compiled to a delegate, not an expression tree; if you want truly equivalent code, you should perhaps use persons.AsQueryable().Where(...), which forces it to use the expression-tree API

    – Marc Gravell
    Nov 23 '18 at 10:49














3












3








3








I'm having some problems with C# dynamic generated lambda expressions.



Considering the following scenario:



public class Person {
public long Id { get; set; }
public string Name { get; set; }
}

List<Person> persons = new List<Person> () {
new Person { Id = 1, Name = "Foo" },
new Person { Id = 2, Name = "Bar" },
new Person { Id = 3, Name = "Baz" },
new Person { Id = 4, Name = null },
};


Now, doing the follow code



ParameterExpression param = Expression.Parameter(typeof(Person), "arg");
Expression prop = Expression.Property(param, "Name");
Expression value = Expression.Constant("bar");
Type type = prop.Type;

MethodInfo toLower = typeof(String).GetMethod("ToLower", Type.EmptyTypes);
Expression expLower = Expression.Call(prop, toLower);

Expression clausule = Expression.Call(expLower, type.GetMethod("Contains", new { type }), value);
Expression notNull = Expression.NotEqual(prop, Expression.Constant(null));

clausule = Expression.And(notNull, clausule);

var exp = Expression.Lambda<Func<T, bool>>(clausule, param);


The above code generate the following exp.



//arg => ((arg.Name != null) And (arg.Name.ToLower().Contains("bar")))


Now, trying to apply that to my list.



The filter below works



var filteredListThatWorks = persons.Where(arg => arg.Name != null && arg.Name.ToLower().Contains("bar")).ToList();


The one below throws exception of Null object ( because of Id 4 name)



var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();


The same expression, when generated by lambda, throws exp, when manually inputed, works.
Anyone knows a way to solve that ?



Br,










share|improve this question














I'm having some problems with C# dynamic generated lambda expressions.



Considering the following scenario:



public class Person {
public long Id { get; set; }
public string Name { get; set; }
}

List<Person> persons = new List<Person> () {
new Person { Id = 1, Name = "Foo" },
new Person { Id = 2, Name = "Bar" },
new Person { Id = 3, Name = "Baz" },
new Person { Id = 4, Name = null },
};


Now, doing the follow code



ParameterExpression param = Expression.Parameter(typeof(Person), "arg");
Expression prop = Expression.Property(param, "Name");
Expression value = Expression.Constant("bar");
Type type = prop.Type;

MethodInfo toLower = typeof(String).GetMethod("ToLower", Type.EmptyTypes);
Expression expLower = Expression.Call(prop, toLower);

Expression clausule = Expression.Call(expLower, type.GetMethod("Contains", new { type }), value);
Expression notNull = Expression.NotEqual(prop, Expression.Constant(null));

clausule = Expression.And(notNull, clausule);

var exp = Expression.Lambda<Func<T, bool>>(clausule, param);


The above code generate the following exp.



//arg => ((arg.Name != null) And (arg.Name.ToLower().Contains("bar")))


Now, trying to apply that to my list.



The filter below works



var filteredListThatWorks = persons.Where(arg => arg.Name != null && arg.Name.ToLower().Contains("bar")).ToList();


The one below throws exception of Null object ( because of Id 4 name)



var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();


The same expression, when generated by lambda, throws exp, when manually inputed, works.
Anyone knows a way to solve that ?



Br,







c# lambda reflection






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 23 '18 at 10:38









Lucas FreitasLucas Freitas

4502928




4502928








  • 1





    also keep in mind - when you use var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();, that is being compiled to a delegate, not an expression tree; if you want truly equivalent code, you should perhaps use persons.AsQueryable().Where(...), which forces it to use the expression-tree API

    – Marc Gravell
    Nov 23 '18 at 10:49














  • 1





    also keep in mind - when you use var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();, that is being compiled to a delegate, not an expression tree; if you want truly equivalent code, you should perhaps use persons.AsQueryable().Where(...), which forces it to use the expression-tree API

    – Marc Gravell
    Nov 23 '18 at 10:49








1




1





also keep in mind - when you use var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();, that is being compiled to a delegate, not an expression tree; if you want truly equivalent code, you should perhaps use persons.AsQueryable().Where(...), which forces it to use the expression-tree API

– Marc Gravell
Nov 23 '18 at 10:49





also keep in mind - when you use var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();, that is being compiled to a delegate, not an expression tree; if you want truly equivalent code, you should perhaps use persons.AsQueryable().Where(...), which forces it to use the expression-tree API

– Marc Gravell
Nov 23 '18 at 10:49












1 Answer
1






active

oldest

votes


















6














And is &; you want to use AndAlso (&&):



clausule = Expression.AndAlso(notNull, clausule);


When in doubt, sharplab.io is an excellent tool here; if I use:



Expression<Func<Person, bool>> filter
= arg => arg.Name != null && arg.Name.ToLower().Contains("bar");


it tells me that it compiles to be equivalent to:



// ...
BinaryExpression body = Expression.AndAlso(left, Expression.Call(instance, method, obj));
// ...


(note that it has to lie about some of the instructions though, as it compiles to things that can't actually be expressed in raw C#)



see it in action






share|improve this answer
























  • You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

    – Lucas Freitas
    Nov 23 '18 at 10:49












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445071%2fc-sharp-reflection-expression-linq%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









6














And is &; you want to use AndAlso (&&):



clausule = Expression.AndAlso(notNull, clausule);


When in doubt, sharplab.io is an excellent tool here; if I use:



Expression<Func<Person, bool>> filter
= arg => arg.Name != null && arg.Name.ToLower().Contains("bar");


it tells me that it compiles to be equivalent to:



// ...
BinaryExpression body = Expression.AndAlso(left, Expression.Call(instance, method, obj));
// ...


(note that it has to lie about some of the instructions though, as it compiles to things that can't actually be expressed in raw C#)



see it in action






share|improve this answer
























  • You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

    – Lucas Freitas
    Nov 23 '18 at 10:49
















6














And is &; you want to use AndAlso (&&):



clausule = Expression.AndAlso(notNull, clausule);


When in doubt, sharplab.io is an excellent tool here; if I use:



Expression<Func<Person, bool>> filter
= arg => arg.Name != null && arg.Name.ToLower().Contains("bar");


it tells me that it compiles to be equivalent to:



// ...
BinaryExpression body = Expression.AndAlso(left, Expression.Call(instance, method, obj));
// ...


(note that it has to lie about some of the instructions though, as it compiles to things that can't actually be expressed in raw C#)



see it in action






share|improve this answer
























  • You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

    – Lucas Freitas
    Nov 23 '18 at 10:49














6












6








6







And is &; you want to use AndAlso (&&):



clausule = Expression.AndAlso(notNull, clausule);


When in doubt, sharplab.io is an excellent tool here; if I use:



Expression<Func<Person, bool>> filter
= arg => arg.Name != null && arg.Name.ToLower().Contains("bar");


it tells me that it compiles to be equivalent to:



// ...
BinaryExpression body = Expression.AndAlso(left, Expression.Call(instance, method, obj));
// ...


(note that it has to lie about some of the instructions though, as it compiles to things that can't actually be expressed in raw C#)



see it in action






share|improve this answer













And is &; you want to use AndAlso (&&):



clausule = Expression.AndAlso(notNull, clausule);


When in doubt, sharplab.io is an excellent tool here; if I use:



Expression<Func<Person, bool>> filter
= arg => arg.Name != null && arg.Name.ToLower().Contains("bar");


it tells me that it compiles to be equivalent to:



// ...
BinaryExpression body = Expression.AndAlso(left, Expression.Call(instance, method, obj));
// ...


(note that it has to lie about some of the instructions though, as it compiles to things that can't actually be expressed in raw C#)



see it in action







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 23 '18 at 10:43









Marc GravellMarc Gravell

793k19821612565




793k19821612565













  • You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

    – Lucas Freitas
    Nov 23 '18 at 10:49



















  • You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

    – Lucas Freitas
    Nov 23 '18 at 10:49

















You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

– Lucas Freitas
Nov 23 '18 at 10:49





You deserve a cookie Sir! 4 more mins to mark as Correct. Thank you very much

– Lucas Freitas
Nov 23 '18 at 10:49




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445071%2fc-sharp-reflection-expression-linq%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

RAC Tourist Trophy