c# - can I have a nested lambda expression stored in a Dictionary? -
i'd parse string lambda expression in c#, example, parse "lt 5"
x => x < 5
can use argument of enumerable.where
:
static void main(string[] args) { enumerable .range(0,10) .select(x => (double)x) .where(parse("lt 5")) .tolist() .foreach(system.console.writeline); } private const list<tuple<list<string>, func<double, func<double, bool>>>> operationlist = new dictionary<string, func<double, func<double, bool>>>() { { "lt <", val => ( x => x < val ) } , { "le <=", val => ( x => x <= val ) } , { "eq = ==" , val => ( x => x == val ) } , { "ne != <>", val => ( x => x != val ) } , { "ge >=", val => ( x => x >= val ) } , { "gt >", val => ( x => x > val ) } } .select(kv => new tuple< list<string>, func<double, func<double, bool>>>( kv.key.split(' ').tolist(), kv.value)) .tolist(); public static func<double, bool> parse(string raw) { var fields = raw.split(' '); var predkey = fields[0].tolower(); var predbuilder = operationlist.firstordefault(tp => tp.item1.firstordefault(key => key.equals(predkey)) != null); return predbuilder.item2(double.parse(fields[1])); }
first made operationlist
stores tuple item1
describes aliases operator , item2
stores curried version of operator.
then parse
split string lt 5
["lt","5"]
, search operation according key lt
.
finally, if can find operation, 5
partial applied , result lambda expression x => x < val
.
however, compiler mad @ { "lt <", val => ( x => x < val ) }
, complained "expression cannot contain anonymous methods or lambda expressions".
i have no idea means , how things work.
change const
readonly
, make static
, so:
private readonly static list<tuple<list<string>, func<double, func<double, bool>>>> operationlist = new dictionary<string, func<double, func<double, bool>>>() { { "lt <", val => ( x => x < val ) } , { "le <=", val => ( x => x <= val ) } , { "eq = ==" , val => ( x => x == val ) } , { "ne != <>", val => ( x => x != val ) } , { "ge >=", val => ( x => x >= val ) } , { "gt >", val => ( x => x > val ) } } .select(kv => new tuple< list<string>, func<double, func<double, bool>>>( kv.key.split(' ').tolist(), kv.value)) .tolist();
in c# const keyword used denote compile time constants, in example list calculated @ runtime using linq.
in c# const
values static , making readonly change field's scope instance.
note, contents of list might change during execution , readonly
won't stop removing , adding tuples list. consider using readonlycollection (it's still won't stop modifying it, make harder) or using immutable collections (which aren't part of .net bcl)
Comments
Post a Comment