C# 创建包含lambda的列表

C# 创建包含lambda的列表,c#,asp.net-mvc,lambda,expression-trees,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

在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
List List=新列表()//可以接受每个lambda表达式
但是

@foreach(dtSetting.ColumnSettings中的委托函数)
{
@Html.DisplayNameFor(func)//无法从用法中推断类型参数。请尝试显式指定类型参数
}

Html.DisplayNameFor
需要
表达式
参数

您可以为相同类型的
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)
}
//在.cs文件中的某个地方
公共列表GetListToDisplay()
{
var list=新列表();
添加(x=>x.myProperty1);
添加(x=>x.myProperty2);
Add(x=>x.myMethod());
退货清单;
}
//在你看来
@模型MyModel
foreach(GetListToDisplay()中的var expr)
{
@Html.DisplayNameFor(expr)
}

改进@Yeldar的答案,我认为您可以将列表设置为
LambdaExpression
的列表,然后为
创建自己的
displayname。我不太精通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});

    }
}
公共静态类扩展
{
公共静态void displayname for(此HtmlHelper html,LambdaExpression e)
{
如果(e.Parameters.Count!=1)
抛出新的InvalidOperationException(“只接受表单表达式的lambda”);
//聚集类型参数
var valueType=e.ReturnType;
var modelType=e.Parameters[0]。类型;
//带有签名DisplayNameExtensions.DisplayNameFor的Get方法(此HtmlHelper,表达式)
var methodinfos=typeof(DisplayNameExtensions).GetMethods()
.Where(mi=>mi.Name==“DisplayNameFor”)
.ToList();
var methodInfo=methodinfos[1];
//构造泛型方法
var generic=methodInfo.MakeGenericMethod(modelType,valueType);
//调用构造的泛型方法
Invoke(null,新对象[]{html,e});
}
}

可能是
列表
?这不是个好主意。使用表达式树?@mshsayem但Func不是Func@黄天文 你到底是什么意思?什么是使用
Func
?@LeiYang是的,我计划使用表达式树,但我很难定义列设置。。如何设置一个可以接受所有lambda表达式的属性,然后在视图中使用它们?我创建了类似的内容(请参见我的更新),但仍然存在错误//无法从用法推断类型参数。尝试显式指定类型参数@黄天文 你的代码不一样。当我使用
表达式时,您使用
委托
。试试这个,如果它不起作用,告诉我。好吧,似乎可以在IDE中工作,但我想知道MVC是否足够聪明,可以将表达式转换为精确的表达式或基于我们的实际定义的表达式。它足够聪明,但如果你不告诉他这样做,它不会改变对象的类型。@foreach(dtSetting.ColumnSettings中的var func){@Html.DisplayNameFor(func)}抛出错误“模板只能用于字段访问、属性访问、一维数组索引或单参数自定义索引器表达式。”我输入了func,Expression.Body.NodeType变为Convert并导致此错误谢谢..因为需要加快项目,我已经使用了其他难看的方法,但如果有时间,我会测试此方法..似乎可以工作
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});

    }
}