评估表达式中的参数结果<func <tmodel,object =“”>&gt; </func <tmodel,>

时间:2014-05-22 20:40:06

标签: c# asp.net-mvc linq lambda expression-trees

评估代表

我有一个表达式,我使用一个参数,我想在下面的DoSomething函数中使用它的结果。

public void DoSomething <TModel>(Expression<Func<TModel, String>> func){

}

调用DoSomething方法

以下 TModel 名称属性中有一个名称列表,我想在DoSomething方法中访问该名称。我无法弄清楚如何做到这一点。

DoSomething(m => m.Names);

试图在没有成功的情况下编译

... 
func.Compile().Invoke([need m.Names]) in here. 

我的现实代码看起来像这样

public static HelperResult TestFor<TModel>(
        ExtendedPageBaseClass<TModel> page,
    Expression<Func<TModel, object>> valueField,
    Expression<Func<TModel, object>> displayField,
    Expression<Func<TModel, ICollection>> list, 
        Object defaultValue = null, String changedEvent = null)   
{
    var idField = valueField.GetName();
    var label = displayField.GetName();
    var display = page.Html.NameFor(displayField).ToString();
    var data = list.Compile().Invoke(page.Html.ViewData.Model);
    return IsolatedSelectorFor(page, idField, display, label, data);
}

2 个答案:

答案 0 :(得分:7)

您已定义了由m => m.Names传递给方法的表达式。但是,这只是一个函数,它将TModel作为输入并返回名称列表。请注意,此时您仍然没有传递任何对象。它只是对函数的描述。

因此,您需要拥有模型的实例才能将其传递给函数并调用它。像这样的东西会起作用:

 public static void DoSomething<TModel>(Expression<Func<TModel, List<string>>> selectNamesFunc, TModel model)
 {
     var f = selectNamesFunc.Compile();
     var names = f.Invoke(model);
 }

此方法的用法是:

DoSomething(m => m.Names, modelInstance);

这只是一个如何使用,编译和调用表达式的例子。你需要决定这样的事情是否有意义,并在你的域中找到应用程序。

答案 1 :(得分:0)

你的DoSomething,因为它是一个Func,它将接受一个函数,它接收一个TModel并返回一个字符串。为了在您编写时调用名称列表,您将需要以下重载

public void DoSomething<TModel>(Expression<Func<TModel, IEnumerable<string>>> func) ...

然后将结果传递给每个字符串。我建议使用一个帮助器方法来处理结果字符串的工作,并从每个带有Funcs的DoSomething重载中调用它