获取List项的属性

时间:2011-05-23 20:19:41

标签: c# reflection properties

Les说我上课了:

class SomeObject
{
  public string Name{get;set;}
  public string SomeProperty {get; set;}
}

我还有SomeObjects的列表:

List<SomeObject> list1 = new List<SomeObject>();
list1.Add(new SomeObject{ Name="Jhon", SomeProperty="baa bla bla"});
list1.Add(new SomeObject{ Name="Albert", SomeProperty="some description"});
list1.Add(new SomeObject{ Name="Tom", SomeProperty="some text"});

我想创建一个类,我可以通过传递我想要填充的列表视图以及列表来填充ListView。因此我的那个类的构造函数就像:

class MyListView
{
    //Constructor
    public MyListView(System.Windows.Controls.ListView listView, object list)
    {
          Lista = ((IEnumerable)list).Cast<object>().ToList(); // Cast the object list to List<objects>

          var properties = Lista[0].GetType().GetProperties();

          foreach (var prop in properties)
          {
              // prop = Name then SomeProperty in this case
              // create new column in listView
              // etc
          }

    }
}

唯一的问题是,如果传递没有对象的列表我不知道如何获取SomeObject的属性,因为我的构造函数假设列表不为空,因此通过获取第一个对象,它可以尝试看到属性。

所以我的问题是如何通过查看列表来获取Name和SomeProperty的属性。我希望做类似的事情:

public MyListView(System.Windows.Controls.ListView listView, object list)
{
   Lista = ((IEnumerable)list).Cast<object>().ToList(); // Cast the object list to List<objects>
   properties = Lista.GetType().GetProperty("some property that refers to list items").GetType().GetProperties();

而不是试图从第一个对象获取它们。我知道我可以修改构造函数并需要一个构造列表的对象并从该对象获取属性但是如果我不必传递那个额外的参数那将会很好。

4 个答案:

答案 0 :(得分:4)

如果您假设list将是IEnumerable的“某事”,为什么不继续使用类型参数指定。然后,即使列表恰好为null或为空,您也可以获取该类型:

public class MyListView<T>{
    //Constructor
    public MyListView(System.Windows.Controls.ListView listView, IEnumerable<T> list)
    {
          var properties = typeof(T).GetProperties();

          foreach (var prop in properties)
          {
              // prop = Name then SomeProperty in this case
              // create new column in listView
              // etc
          }
    }
}

// Example usage: Inferred type parameter 
List<SomeObject> list = null;
var yourListView = new MyListView(listView1, list);

// Example usage: Explicitly specify the type parameter if it can't be inferred
var yourListView = new MyListView<SomeObject>(listView1, null);

答案 1 :(得分:1)

当你调用MyListView构造函数时,你知道SomeObject类的类型吗?如果是这样,你可以使用泛型

答案 2 :(得分:0)

取自http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx

        Type d1 = typeof(List<int>);
        Type[] typeParameters = d1.GetGenericArguments();

在这种情况下,typeParametes [0]保存类型System.Int32。

希望这有帮助。

答案 3 :(得分:-1)

你会想要做这样的事情。

if(list.Count>0)
{
    var firstItem = list[0];
    var type = response.GetType();

    PropertyInfo nameInfo = type.GetProperty("Name");
    nameInfo.GetValue(firstItem, null);                 //returns list[0].Name
    nameInfo.SetValue(firstItem, "somevalue", null); ;  //sets list[0].Name to "somevalue"

    PropertyInfo someInfo = type.GetProperty("SomeProperty");
    someInfo.GetValue(firstItem, null);                 //returns list[0].SomeProperty
    someInfo.SetValue(firstItem, "somevalue", null); ;  //sets list[0].SomeProperty to "somevalue"
}

if块确保您不会尝试反映空对象。然后我们从那里得到TypePropertyInfoPropertyInfo允许您访问属性的元数据,并获取或设置值。我在setter中使用"somevalue"但它可以接受任何类型。最后一个参数是您的属性是否已编入索引,但您没有表明它是如此null将正常工作。

这适用于列表中的第一个对象。如果您需要反映整个列表,则需要在循环中进行设置。