【问题标题】:Function predicate to string函数谓词到字符串
【发布时间】:2019-02-17 15:19:11
【问题描述】:

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

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") AndAlso (ReportModel.Surname == "Jones"))。

非常感谢任何帮助,

【问题讨论】:

  • 我相信您正在尝试检查名字为“Peter”且姓氏为“John”的ReportModel,然后将结果返回为RecordViewModel,对吗?
  • 不,ReportModel 是来自 UI 的参数,并且希望将过滤条件记录为字符串
  • 所以返回应该是字符串而不是布尔值?
  • 是的,一个字符串,例如 ((ReportModel.Firstname == "Peter") AndAlso (ReportModel.Surname == "Jones"))。类似stackoverflow.com/questions/15478711/…
  • 我还是不明白。

标签: c# linq lambda delegates


【解决方案1】:

如果你想返回一个字符串,这应该是你的表达式:

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" });

【讨论】:

  • 抱歉,我无法更改谓词,我只想用填充的值序列化谓词
【解决方案2】:

所以,如果我对您的理解正确,您会得到一个 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"))

在那里,您使用一些反射来获取 func 的参数(并且您知道总是有 1 个)以进行比较。然后根据名称查找该参数的属性。

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

而且,显然,您还对结果字符串的表示进行了硬编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2016-09-12
    • 1970-01-01
    相关资源
    最近更新 更多