c# - Passing a Func<T, TResult> where TResult is unknown -
note: please re-tag and/or re-name appropriately
i have class, fooenumerator
, wraps foo
, implements ienumerable<fooenumerator>
. foo
s represent tree-like data structure, fooenumerator
s enumerated child nodes of current node.
foo
vendor supplied data object. fooenumerator
implements bunch of custom filtering code.
class fooenumerator : ienumerable<fooenumerator> { public foo wrappednode { get; private set; } public string name { { return wrappednode.name; } } public int id { get{ return wrappednode.id; } } public datetime created { get{ return wrappednode.created; } } public fooenumerator(foo wrappednode) { wrappednode = wrappednode; } public ienumerator<fooenumerator> getenumerator() { foreach (foo child in this.getchildren()) if(filteringlogicinhere(child)) yield return new fooenumerator(child); } ... }
i want able sort each level of tree given (arbitrary) expression, defined when top level fooenumerator
created, , have expression passed down each newly enumerated item use.
i'd define sort expression using lambda's, in same way orderby function. in fact, intention pass lambda orderby
.
the signiture orderby
orderby<tsource, tkey>(func<tsource, tkey> keyselector)
where tkey
return type of given func
, type parameter in method signature , figured out @ compile time.
example usage
var x = getstartingnode(); var sort = n => n.datetime; var enu = new fooenumerator(x, sort); var sort2 = n => n.name; var enu2 = new fooenumerator(x, sort2);
the sort expression stored in class variable , fooenumerator
work like:
// pseudo-implementation private expression<func<foo, tkey>> _sortby; public fooenumerator(foo wrappednode, expression<func<foo, tkey>> sortby) { wrappednode = wrappednode; _sortby = sortby; } public ienumerator<fooenumerator> getenumerator() { foreach (foo child in this.getchildren().orderby(_sortby)) if(filteringlogicinhere(child)) yield return new fooenumerator(child); }
how can specify type of tkey (implicitly or explicitly) in use case?
i don't want hard code want able sort on , properties of underlying foo
.
well, can't create member delegate variable of type expression<func<foo,tkey>>
since tkey
never specified. however, create member of type expression<func<foo,icomparable>>
may suffice purposes. need change fooenumerator
constructor accept signature well, of course.
edit: others have suggested parameterizing fooenumerator
accepts tkey
. can this, should aware of issues emerge:
- by parameterizing enumerator kicking bucket down road. code wants store
fooenumerator<t>
has have a-priori knowledge of typet
. could, however, implement non-generic interfaceifooenumerator
deal that. - parameterizing enumerator creates issues if want support ordering on multiple fields in future. c# doesn't support generics variable number of type parameters, limits creation of generics require multiple arbitrary types. issue harder deal with, since it's awkward start creating
fooenumerator<t>
,fooenumerator<t1,t2>
,fooenumerator<t1,t2,t3...>
, , on.
Comments
Post a Comment