基于lambda表达式创建匿名类型

时间:2009-04-16 20:24:23

标签: lambda anonymous-types c# datasource

我正在尝试为Winforms Datagrid创建一个Fluent接口。这应该允许我使用类型化数据源并轻松使用属性属性(Order.Custom.FullName)

我在初始化时添加了列,并尝试将属性设置为在那里使用:

dgv.With<Order>().Column("Client Name").On(x => x.Client.FullName);

在设置数据源时,原始问题就出现了:

dgv.SetTypedDatasource<T>(IList<Order> orders)

这里的一个大问题是Generic Controls是不可能的(我猜),所以不能为类指定T,但必须按照方法指定......

我想根据lambda表达式中的给定属性创建一个匿名类型列表:

类似的东西:

ProcessList<Client>(clientList, x => x.FullName);

是否可以做这样的事情:

[编辑]请注意,在实践中,表达式将在之前设置,并将在其他地方提取......

public void ProcessList<T>(IList<T> sourceList, Expression<Func<T, object>> expression)
{
    var list =
        (from T x
         in sourceList
         select new { expression })
         .ToList();

    // process list ....  grid.DataSource = list;
}

所以,我想基于给定的表达式创建匿名类型。我知道我可以评估该表达式以检索正确的属性。

我有点卡住,这样的事情可能吗?

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

嗯,通过简单的Select来电,你可以非常接近:

ProcessList(clientList.Select(x => new { x.FullName }));

...

public void ProcessList<T>(IEnumerable<T> list)
{
    // process list ... T will be an anonymous type by now
    grid.DataSource = list;
}

(假设您不需要ProcessList中的原始列表。如果您这样做,请将选择移到那里。)

答案 1 :(得分:2)

不只是grid.DataSource = sourceList.AsQueryable().Select(expression).ToList();

请注意,最好引入第二个通用名称,以便输入列表:

    public static void ProcessList<TSource, TValue>(
        IList<TSource> sourceList,
        Func<TSource, TValue> expression)
    {
        grid.DataSource = sourceList.Select(expression).ToList();
    }

注意我从Expression<...>切换到Func<...>,因为它似乎毫无用处。