Reputation: 2709
I need to loop through a list where the type is not known at compile-time. How to do that? The following code fails at runtime, conversion not allowed:
Type objType = dataObject.GetType();
List<string> strList = new List<string>();
foreach (PropertyInfo prop in objType.GetProperties())
{
var val = prop.GetValue(dataObject);
if (prop.PropertyType.Name.StartsWith("List")) // Is there a better way?
{
foreach (object lval in (List<object>) val) // Runtime failure (conversion not allowed)
{
strList.Add(lval.ToString());
}
}
...
Upvotes: 4
Views: 8130
Reputation: 13381
maybe it will be easier
foreach (PropertyInfo prop in objType.GetProperties())
{
var val = prop.GetValue(x,null);
if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType.IsGenericType) // Is there a better way?
{
dynamic dd = val;
foreach (object lval in dd)
{
strList.Add(lval.ToString());
}
}
Upvotes: 0
Reputation: 5121
foreach (var propInfo in foobar.GetType().GetProperties())
{
var val = propInfo.GetValue(foobar, null);
if (typeof(IEnumerable).IsAssignableFrom(propInfo.PropertyType))
{
var collectionItems = (IEnumerable)val;
if (collectionItems != null)
{
foreach (object lval in collectionItems)
{
Console.WriteLine(lval);
}
}
}
}
Upvotes: 0
Reputation: 68660
Just wanted to add something to what has already been said:
Your logic is flawed because List<int>
(for example) is not a subclass of List<object>
. List<T>
is not covariant in its type parameter.
If it was, it would be legal to do this:
List<object> listOfObjects = new List<int>();
listOfObjects.Add("a string");
Read this to learn more about covariance/contravariance in C#:
http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx
Upvotes: 1
Reputation: 1062810
If you don't know the type, then : generics may not be the best option:
IList list = val as IList; // note: non-generic; you could also
// use IEnumerable, but that has some
// edge-cases; IList is more predictable
if(list != null)
{
foreach(object obj in list)
{
strList.Add(obj.ToString());
}
}
Upvotes: 7