函数谓词为字符串

时间:2018-09-12 22:38:35

标签: c# linq lambda delegates

我对表达的学习真的很基础,我有以下函数谓词

Func<RecordViewModel, Func<ReportModel, bool>> exp = rec => x => x.Firstname == rec.Firstname &&
                                                                 x.Surname == rec.Surname;

var func = exp(new RecordViewModel() { Firstname= "Peter", Surname  = "Jones" });

以下是我的模型和视图模型,

public class ReportModel
{
    public string Firstname { get; set; }
    public string Surname { get; set; }
}
public class RecordViewModel
{
    public string Firstname { get; set; }
    public string Surname { get; set; }
}

我想将表达式序列化为 (((ReportModel.Firstname ==“ Peter”)AndAndso(ReportModel.Surname ==“ Jones”))。

对此的任何帮助,我们将不胜感激,

2 个答案:

答案 0 :(得分:0)

如果要返回字符串,则应为您的表达式:

Func<RecordViewModel, string> exp = rec (x) => return x.Firstname == rec.Firstname &&
         x.Surname == rec.Surname ? "ReportModel.Firstname" + x.Firstname + " " 
         + "ReportModel.Surname" + " "  rec.Surname : string.empty;

然后您可以通过传递Model来调用表达式:

var func = exp(new RecordViewModel() { Firstname= "Peter", Surname  = "Jones" });

答案 1 :(得分:0)

因此,如果我对您的理解正确,那么您会得到一个Func(在您的示例中称为exp),并且需要为其提供toString方法。

您可以使用以下内容:

Func<Func<ReportModel, bool>, string> toString = func => 
{
    var vm = ((dynamic)func.Target).rec;
    var paramType = func.Method.GetParameters()[0].ParameterType;
    var firstNameProperty = paramType.GetProperties().First(p => p.Name == nameof(vm.Firstname)).Name;
    var surnameProperty = paramType.GetProperties().First(p => p.Name == nameof(vm.Surname)).Name;
    return $"(({paramType.Name}.{firstNameProperty} == \"{vm.Firstname}\") AndAlso ({paramType.Name}.{surnameProperty} == \"{vm.Surname}\"))";
};

Console.WriteLine(toString(exp(viewModel))); 
//returns ((ReportModel.Firstname == "Peter") AndAlso (ReportModel.Surname == "Jones"))

在其中您需要进行一些反射以获取函数的参数(并且您知道,其中始终有1个)进行比较。然后您会根据名称查找该参数的属性。

dynamic还有一个小技巧,可以获取rec值(您的RecordViewModel)。它可能很脏,但是如果可行...

很显然,您还对所得字符串的表示形式进行了硬编码。