Evaluate Parameter Result Within Expression>

asp.net-mvc c# expression-trees lambda linq

Question

Evaluate the Delegate

I have an expression that I use a parameter with which I want to use the result of within my DoSomething function below.

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

}

Call the DoSomething Method

The following TModel has a list of names in the Names property which I would like to access from within the DoSomething method. I can't figure out how to do this.

DoSomething(m => m.Names);

Tried to Compile Without Much Success

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

My Code in Reality Looks Something Like This

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);
}
1
3
5/22/2014 9:20:51 PM

Accepted Answer

You have defined expression which you pass to your method by m => m.Names. However that is only function which, takes as input your TModel and returns list of names. Note that at that point you still did not pass any object. It is just a description of the function.

So, you need to have an instance of the model in order to pass it to the function and invoke it. Something like this would work:

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

Usage of this method would be:

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

This is only only an example, of how to use, compile and invoke from expression. You need to decide if something like that makes sense and finds application in your domain.

8
5/22/2014 9:11:01 PM

Popular Answer

Your DoSomething, since it's a Func, will take in a function which takes in a single TModel and returns a single string. In order to invoke against a list of names, as you're written, you'll need the following overload

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

And then to pass over each string as the result. I recommend using a helper method to handle the work on resulting strings, and calling this from each of the DoSomething overloads taking in Funcs



Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow