Wednesday, 13 February 2008

Obtaining generic list item instances using reflection

I've decided to use my blog as a space to share what I think may be useful links, code examples, and information about ASP.NET, C# and general software engineering tips or workaround's I may have come upon.

So let me begin with a simple bit of code that may prove useful to some people.

I had a problem where I was using reflection that required a method to be invoked. This method returned a generic list of items. The problem was that using reflection the type that was returned from the method was "System.Collections.Generic.List`1[T]", and I needed a way to loop through the actual items in the list, in order to check types and property values.

The solution is pretty straightforward. There is a method in a generic list object that allows you to retrieve a single item based on it's index. The method name is "get_Item". Below is a small section of C# code that will show you how it works:

// Create an instance of the type you require
Type myType = "AssemblyName.TypeName, AssemblyName";
object instance = Activator.CreateInstance(typeof(myType));
// Invoke the method
MethodInfo method = myType.GetType().GetMethod("MethodName");
// The list object is of type "System.Collections.Generic.List`1[T]"
object list = method.Invoke(instance, null);
// Get the list item count
int listCount = (int)list.GetType().GetProperty("Count").GetValue(list, null);
// Loop though generic list
for (int index = 0; index <= listCount; index++)
{
// Get an instance of the item in the list
object item = list.GetType().GetMethod("getItem").Invoke(list, new object[] { index });
// Now you have an instance of the item in the generic list
//....
// TODO: Place additional code here/
//....
}

Hope that may help some of you out there. :)

4 comments:

Anonymous said...

Cool, thanks very much, but your method name is misspelled in the code (getItem instead of get_Item)

Anonymous said...

Also the index test should be < instead of <=

dnoxs said...

Thank you for your comments.

Anonymous said...

thanks for the good information.

I tried to call method with list paramter using reflection, I used your posted code but, I'm facing error at code "object list = method.Invoke(instance, null); // Here Error throws - "Parameter count mismatch."".
/////////////////////////////

My complete test code here:


class Test
{
public void A(List depts)
{

}
public void B()
{

}
}

class Department
{
public string Name { get; set; }
public int DeptNo { get; set; }
}

public class Program
{
public static void SetListPropetyValue()
{
Type type = typeof(Test);
object instance = Activator.CreateInstance(type);
// Invoke the method
MethodInfo method = instance.GetType().GetMethod("A");
// The list object is of type "System.Collections.Generic.List`1[T]"
object list = method.Invoke(instance, null); // Here Error throws - "Parameter count mismatch."
// Get the list item count
int listCount = (int)list.GetType().GetProperty("Count").GetValue(list, null);
// Loop though generic list
for (int index = 0; index <listCount; index++)
{
// Get an instance of the item in the list
object item = list.GetType().GetMethod("get_Item").Invoke(list, new object[] { index });
// Now you have an instance of the item in the generic list //.... // TODO: Place additional code here/ //....
}

}
public static void Main(string[] args)
{
// calling set list property value
SetListPropetyValue();
}
}

/////////// end

can you please help me on this ? Thanks - Sunil