这是我的班级
class SampleExpression
{
public string str;
public static bool SampleEnum(SampleExpression s, IEnumerator<string> ien = null)
{
while (ien.MoveNext())
{
if (s.str == ien.Current)
{
ien.Reset();
return true;
}
}
return false;
}
}
这就是我在运行时生成表达式树的方法:
static void Main(string[] args)
{
ParameterExpression param1 = Expression.Parameter(typeof(SampleExpression), "token");
ParameterExpression param2 = Expression.Parameter(typeof(IEnumerator<string>), "args");
var lstConstant = "1,2,3,4,".Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries).ToList();
var enummethod = typeof(SampleExpression).GetMethod("SampleEnum");
MethodCallExpression methodCall = Expression.Call
(
enummethod,
param1
, param2
);
var e = Expression.Lambda<Func<SampleExpression, IEnumerator<string>, bool>>(methodCall, param1, param2);
var l = e.Compile();
List<SampleExpression> lst = new List<SampleExpression>();
lst.Add(new SampleExpression { str = "1" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "2" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "5" });
var items = lst.Where(x => l(x, lstConstant.GetEnumerator())).ToList();
}
现在我可能会以一种错综复杂的方式做到这一点(因为我是Expression树的新手) - 我的要求是:
我有一个逗号分隔的字符串,如"1,2,3,4,"
。我想将每个SampleExpression
拆分并与类str
的字符串参数SampleExpression
进行匹配。到目前为止,我已经做了。
但我希望表达式为Func<SampleExpression,bool>
。正如您可以看到它的Func<SampleExpression, IEnumerator<string>, bool>
。
我该如何解决这个问题。
答案 0 :(得分:2)
表达式汇编对我来说似乎很奇怪,但要真正回答你的问题......
您可以像这样包装已编译的Func:
Func<SampleExpression, bool> lBind = (SampleExpression token) => l(token, lstConstant.GetEnumerator());
这会将枚举数绑定为第二个参数,同时将第一个参数保留为输入。
答案 1 :(得分:1)
我不清楚为什么你要进行动态表达式编译,所以我只关注你的问题陈述:
我有一个逗号分隔的字符串,如
"1,2,3,4,"
。我想将每个SampleExpression
拆分并与类str
的字符串参数SampleExpression
进行匹配。
LINQ实际上提供了一种非常简单的方法来处理这个问题:
var lstConstant = "1,2,3,4,".Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries).ToList();
List<SampleExpression> lst = new List<SampleExpression>();
lst.Add(new SampleExpression { str = "1" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "2" }); // matches with lstConstant
lst.Add(new SampleExpression { str = "5" });
var items = lst.Where(x => lstConstant.Contains(x.str)).ToList();
如果你想让这个逻辑驻留在SampleExpression
类中,那很好:
class SampleExpression
{
public string str;
public static bool SampleEnum(SampleExpression s, IEnumerable<string> ien)
{
return ien.Contains(s.str);
}
}
// Usage:
var items = lst.Where(x => SampleExpression.SampleEnum(x, lstConstant))
.ToList();
如果您希望SampleEnum
方法本身返回值以传递到Where
子句,则可以改为:
class SampleExpression
{
public string str;
public static Func<SampleExpression, bool> SampleEnum(IEnumerable<string> ien)
{
return s => ien.Contains(s.str);
}
}
// Usage:
var items = lst.Where(SampleExpression.SampleEnum(lstConstant))
.ToList();