Reputation: 36080
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
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
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
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
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