创建包含lambda的列表

时间:2015-12-03 03:15:30

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

在C#中,如何创建一个可以包含lambda的列表?

我能写的东西:

//Declare list here
list.Add(model => model.Active);
list.Add(model => model.Name);

以后我可以访问视图中的列表

@foreach(var lambda in list)
    @Html.DisplayNameFor(lambda)
@next

如何定义此列表?

更新

List<Delegate> list = new List<Delegate>(); //Can accept every lambda expression

@foreach (Delegate func in dtSetting.ColumnSettings)
{
    <th width="10%">
        @Html.DisplayNameFor(func) // The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly
    </th>
}

2 个答案:

答案 0 :(得分:0)

Html.DisplayNameFor需要Expression<Func<TModel, TValue>> expression参数。

您可以创建相同List类型的TModel个此类对象并使用它:

// Somewhere in .cs file
public List<Expression<Func<MyModel, object>>> GetListToDisplay()
{
  var list = new List<Expression<Func<MyModel, object>>>();

  list.Add(x => x.myProperty1);
  list.Add(x => x.myProperty2);
  list.Add(x => x.myMethod());

  return list;
}

// In your View
@model MyModel  
foreach (var expr in GetListToDisplay())
{
    @Html.DisplayNameFor(expr)
}

答案 1 :(得分:0)

改善@ Yeldar的回答,我认为您可以将列表列为LambdaExpression,然后制作自己的DisplayNameFor。我对ASP.NET MVC并不那么精通,但这可能会让你走上正确的道路:

public static class Extensions
{
    public static void DisplayNameFor(this HtmlHelper html, LambdaExpression e)
    {
        if(e.Parameters.Count != 1)
            throw new InvalidOperationException("Only lambdas of form Expression<Func<TModel, TValue>> are accepted.");

        //Gather type parameters
        var valueType = e.ReturnType;
        var modelType = e.Parameters[0].Type;

        //Get method with signature DisplayNameExtensions.DisplayNameFor<TModel, TValue>(this HtmlHelper<TModel>, Expression<Func<TModel,TValue>>)
        var methodinfos = typeof (DisplayNameExtensions).GetMethods()
            .Where(mi => mi.Name == "DisplayNameFor")
            .ToList();
        var methodInfo = methodinfos[1];

        //Construct generic method
        var generic = methodInfo.MakeGenericMethod(modelType, valueType);

        //invoke constructed generic method
        generic.Invoke(null, new object[] {html, e});

    }
}