我想将一个字符串解析为 C# 中的 lambda 表达式,例如,解析"lt 5"
为,x => x < 5
以便我可以将其用作以下参数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]));
}
首先,我创建了一个operationList
存储元组的元组,其中Item1
描述了运算符的所有别名,并Item2
存储了运算符的柯里化版本。
然后Parse
将字符串拆分lt 5
为["lt","5"]
根据 key 进行搜索操作lt
。
最后,如果我能找到操作,5
将部分应用于它,结果将是一个 lambda 表达式x => x < val
。
但是,编译器很生气{ "lt <", val => ( x => x < val ) }
并抱怨“表达式不能包含匿名方法或 lambda 表达式”。
我不知道这意味着什么以及如何让事情发挥作用。