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