匿名类型,其中属性在运行时未知

时间:2010-03-26 16:36:19

标签: c# anonymous-types

我有以下场景,我想创建一个DataGrid,然后在运行时填充内容。

我遇到的问题是,因为在创建网格之前我不知道字段是什么,所以我不知道如何正确设置项目源。正如你在下面的代码中看到的那样,我将字段名称添加为列,然后循环遍历我的项目,此时我想为每个项目创建一个匿名类型,我在其中设置一个属性(称为其字段名称)到字段名称值

foreach (string fieldName in listViewFieldCollection)
{
    DataGridTextColumn newColumn = new DataGridTextColumn
                                       {
                                           Header = fieldName,
                                           Binding = new Binding(fieldName)
                                       };

    dataGrid.Columns.Add(newColumn);
}

List<object> list = new List<object>();

foreach (ListItem listItem in listItems)
{
    foreach (string fieldName in listViewFieldCollection)
    {
        list.Add(new
                     {
                         // I want to be able to dynamically build Anonymous type properties here
                         fieldName = listItem[fieldName]
                     });
    }
}

dataGrid.ItemsSource = list;
例如,

。如果我有名为'Title'和'Link'的字段,那么我想要list.Add(new表现为

    list.Add(new
                 {
                     Title = listItem["Title"],
                     Link = listItem["Link"]
                 });

但是如果字段是'经理','标题'和'薪水',它应该像

一样执行
    list.Add(new
                 {
                     Manager = listItem["Manager"],
                     Title = listItem["Title"],
                     Salary = listItem["Salary"],
                 });

2 个答案:

答案 0 :(得分:1)

没有反思或代码生成是不可能的。

new
                 {
                     Manager = listItem["Manager"],
                     Title = listItem["Title"],
                     Salary = listItem["Salary"],
                 }

转换为具有三个字段的类,然后使用几行来设置这些字段。这是由编译器生成的代码。所以在运行时你不能这样做。

答案 1 :(得分:0)

听起来好像使用反射可行。下面的代码可以帮助您入门。该片段将遍历对象上的所有属性。

        foreach (var currentPropertyInformation in source.GetType().GetProperties())
        {
            if ((currentPropertyInformation.GetGetMethod() == null) || (currentPropertyInformation.GetSetMethod() == null)) 
                continue;

            if (string.Compare(currentPropertyInformation.Name, "Item") != 0) // handle non-enumerable properties
            {
                // place this snippet in method and yield info?
            }
            else // handle enumerable properties
            {
            }
        }