![](/img/trans.png)
[英]How do I dynamically create an Expression<Func<MyClass, bool>> predicate from Expression<Func<MyClass, string>>?
[英]How do I dynamically create an Expression<Func<MyClass, bool>> predicate with string parameter?
我有以下 C# 类
public class Contact
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Phone> Phones { get; set; }
}
public class Phone
{
public string AreaCode { get; set; }
public string PhoneNumber { get; set; }
public bool IsMobile { get; set; }
}
下面是我尝试动态创建的示例表达式。
Expression<Func<Contact, bool>> isMobileExpression = p => p.Phone.First().IsMobile;
我想创建一个类似上面的表达式,但动态定义“p.Phone.First().IsMobile”表达式而不是硬编码它。 例如:
var paraName = "p => p.Phone.First().IsMobile";
Expression<Func<Contact, bool>> isMobileExpression = p => paraName;
那有可能吗? 感谢您提前提供任何帮助。
你可以考虑一个CSharpScript :
public class Contact
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Phone> Phones { get; set; }
}
public class Phone
{
public string AreaCode { get; set; }
public string PhoneNumber { get; set; }
public bool IsMobile { get; set; }
}
void Main()
{
var code = "return Phones.First().IsMobile;";
var script = CSharpScript.Create<bool>(code, globalsType: typeof(Contact), options: ScriptOptions.Default.WithReferences("System.Linq").WithImports("System.Linq"));
var scriptRunner = script.CreateDelegate();
Console.WriteLine(scriptRunner(new Contact() { Phones = new List<Phone> { new Phone {IsMobile = true }}} ));
Console.WriteLine(scriptRunner(new Contact() { Phones = new List<Phone> { new Phone {IsMobile = false }}} ));
}
如果你想要一个表达式,你可以像这样将ScriptRunner
委托包装到Expression.Call()
中:
Expression<Func<Contact, Task<bool>>> GetExpression()
{
var code = "return Phones.First().IsMobile;";
var script = CSharpScript.Create<bool>(code, globalsType: typeof(Contact), options: ScriptOptions.Default.WithReferences("System.Linq").WithImports("System.Linq"));
var scriptRunner = script.CreateDelegate();
var p = Expression.Parameter(typeof(Contact));
var mi = scriptRunner.Method;
return Expression.Lambda<Func<Contact, Task<bool>>>(Expression.Call(Expression.Constant(scriptRunner.Target), mi, p, Expression.Constant(CancellationToken.None)), p);
}
然后你会编译并在你认为合适的时候使用它:
void Main()
{
var scriptRunner = GetExpression().Compile();
Console.WriteLine(scriptRunner(new Contact() { Phones = new List<Phone> { new Phone { IsMobile = true } } }));
Console.WriteLine(scriptRunner(new Contact() { Phones = new List<Phone> { new Phone { IsMobile = false } } }));
}
然而,我觉得这有点太令人费解了。 如果您可以直接使用委托,可能会更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.