c# - Create expression tree to assign to property of list -



c# - Create expression tree to assign to property of list -

this has been plaguing me days now....

if have list of own object searchresults , searchresults contains multiple lists of objects, of have match (bool) property, how can recreate look tree accomplish following:

//searchresults list<searchresults> searchresults[i].comments = searchresults[i].comments.select(p1 => { p1.match = listofstringvariable.all(p2 => { string value = (string)typeof(commentdata).getproperty(propertyname).getvalue(p1); homecoming value.contains(p2); }); homecoming p1; }).orderbydescending(x => x.match); .... public class searchresults { public ienumerable<commentdata> comments { get; set; } public ienumerable<advisordata> advisors { get; set; } } public class commentdata { public string commenttext { get; set; } public bool match { get; set; } } public class advisordata { public string firstname { get; set; } public string lastname { get; set; } public bool match { get; set; } }

the look tree needed won't know property @ compile-time needs assigned, whether comments, advisors, etc (as simplification of larger problem). above illustration comments, how same code used assign advisors without having conditional block?

many thanks

update:

so far using reflection have below striplingwarrior

var searchresult = searchresults[i]; foreach (var srproperty in searchresultsproperties) { var collectiontype = srproperty.propertytype; if(!collectiontype.isgenerictype || collectiontype.getgenerictypedefinition() != typeof(ienumerable<>)) { throw new invalidoperationexception("all searchresults properties should ienumerable<something>"); } var itemtype = collectiontype.getgenericarguments()[0]; var itemproperties = itemtype.getproperties().where(p => p.name != "match"); var items = ((ienumerable<ihavematchproperty>) srproperty.getvalue(searchresult)) // materialize enumerable, in case it's backed // re-create objects each time it's iterated over. .tolist(); foreach (var item in items) { var propertyvalues = itemproperties.select(p => (string)p.getvalue(item)); item.match = propertyvalues.any(v => searchterms.any(v.contains)); } var ordereditems = items.orderby(i => i.match); srproperty.setvalue(srproperty, ordereditems); }

however ordereditems of type system.linq.orderedenumerable<ihavematchproperty,bool> , needs cast ienumerable<advisordata>. below throws error:

'system.linq.enumerable.castiterator(system.collections.ienumerable)' 'method' used 'type'

var castmethod = typeof(enumerable).getmethod("cast").makegenericmethod(new[] {propertytype}); var result = castmethod.invoke(null, new[] { ordereditems });

where propertytype type advisordata

first, create types implement interface don't have quite much reflection:

public interface ihavematchproperty { bool match { get; set; } }

then write code this. (i'm making lot of assumptions because question wasn't super clear on intended behavior is.)

var searchresult = searchresults[i]; foreach (var srproperty in searchresultsproperties) { var collectiontype = srproperty.propertytype; if(!collectiontype.isgenerictype || collectiontype.getgenerictypedefinition() != typeof(ienumerable<>)) { throw new invalidoperationexception("all searchresults properties should ienumerable<something>"); } var itemtype = collectiontype.getgenericarguments()[0]; var itemproperties = itemtype.getproperties().where(p => p.name != "match"); var items = ((ienumerable<ihavematchproperty>) srproperty.getvalue(searchresult)) // materialize enumerable, in case it's backed // re-create objects each time it's iterated over. .tolist(); foreach (var item in items) { var propertyvalues = itemproperties.select(p => (string)p.getvalue(item)); item.match = propertyvalues.any(v => searchterms.any(v.contains)); } var ordereditems = items.orderby(i => i.match); srproperty.setvalue(srproperty, ordereditems); }

c# lambda expression-trees

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -