Tono Nam
Tono Nam

Reputation: 36080

Get properties of List item

Les's say I have a class:

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

I also have a list of SomeObjects's:

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"});

I want to create a class where I can populate a ListView by passing the listview that I want to fill and also a list. therefore my constructor of that class is like:

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
          }

    }
}

The only problem is that if a pass a list with no objects I don't know how could I get the properties of SomeObject because my constructor is assuming that the list is not empty therefore by getting the first object it can try to see the properties.

So my question is how could I get the properties of Name and SomeProperty by looking at the list. I am looking to do something like:

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();

Instead of trying to get them from the first object. I know I could modify the constructor and require an object of which the list is constructed and get the properties from that objects but it will be nice if I don't have to pass that extra parameter.

Upvotes: 1

Views: 10328

Answers (4)

user610650
user610650

Reputation:

Taken from http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx:

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

In this case, typeParametes[0] holds the type System.Int32.

Hope this helps.

Upvotes: 0

Rob
Rob

Reputation: 4477

When you call the MyListView constructor, do you know the type of the SomeObject class? If so, you could use generics

Upvotes: 1

Jeff
Jeff

Reputation: 14279

You'll want to do something like this.

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"
}

The if block makes sure that you arent trying to reflect on a null object. Then we get the Type and the PropertyInfo from there. The PropertyInfo allows you to access the meta data for the property and also get or set the value. I used "somevalue" in the setters but it can accept any type. The last parameter is if your property is indexed, but you didnt indicate that it was so null will work fine.

This works just fine for the first object in the list. If you need to reflect over the entire list, you will need to set this up in a loop.

Upvotes: -1

David Ruttka
David Ruttka

Reputation: 14409

If you're making the assumption that the list is going to be an IEnumerable of "something", why not go ahead and specify that by using a type parameter. Then you can get the type even if the list happens to be null or empty:

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);

Upvotes: 4

Related Questions