【问题标题】:Is a Collection of Expression<Func<T, TProp>> possible?Expression<Func<T, TProp>> 的集合是否可能?
【发布时间】:2012-07-31 13:32:49
【问题描述】:

鉴于此代码:

public class PaginationModel<T> : BaseModel
{
    public List<T> Rows { get; set; }

    public PagingInfo PagingInfo { get; set; }

    public void AddColumn<TProp>(Expression<Func<T, TProp>> column)
    {

    }
}

我希望能够使用代码

leadListOutputModel.AddColumn(x => x.DateCreated);

然后在我的 MVC 视图中循环遍历列集合并针对对象调用表达式,但是由于 TProp 是在方法调用中推断出来的,因此它似乎无法存储为通用字段,例如

    private List<Expression<Func<T, TProp>>> columns = new List<Expression<Func<T, TProp>>>();

谁能想到一个不使用对象或失去一般好处的方法?

--- 编辑

我正在尝试做两件事,

首先,我将一个“SortBy”参数传递给我的控制器,它采用字符串属性的名称,当前通过 ((MemberExpression)expression).Member.Name 提取,其次我想使用 Func 在我的 MVC 视图中提取该字段的值。

原因是我正在制作一个分页网格,我希望在控制器中使用一个很好的语法来配置列,例如我给出的 AddColumn 示例。我想查看列以创建标题行,然后在我的模型集合中循环遍历这些列并针对它们调用 Func 以提取值。

【问题讨论】:

  • 我会说List&lt;Expression&lt;Func&lt;T, object&gt;&gt;&gt;,但您认为这会失去通用TProp 的好处。你能详细说明一下吗?它有什么好处?
  • 回复:您的编辑:是的;我以前做过。您需要一组非泛型接口,以及由泛型 AddColumn 方法创建的泛型实现。

标签: c# linq generics collections expression


【解决方案1】:

之后你想对这些列做什么?您以后不能真正使用任何关于结果类型的编译时信息,因为它可能因调用而异:

AddColumn(x => x.SomeInt32Value);
AddColumn(x => x.SomeDateTimeValue);

如果它们将存储在同一个集合中,那么您将 选择转换或使用更通用的形式。

您可能要考虑使用:

public void AddColumn(Expression<Func<T, object>> column)

就“源”类型而言,它仍然是安全的......您将失去“结果”类型,但我认为这对您没有用处。

【讨论】:

  • 这将阻止您添加直接返回值类型的属性或函数(而不是传递自动装箱 lambda)。
  • @SLaks:好吧,鉴于它使用的是表达式树而不是委托,因此您无论如何都无法使用方法组转换......所以如果您有其他表达式,这只会是一个问题树木已经建成。
【解决方案2】:

听起来您正在尝试创建一个集合,其中每个实例都有一个不同 TProp
这是不可能的。

相反,您可以创建实现非泛型接口的泛型类。
然后,您可以创建非泛型接口的集合,并通过泛型方法将泛型类的实例添加到集合中。

有关此技术的示例,请参阅我的 ExcelExporter library 及其通用 SheetBase class

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多