Reputation: 9314
I have a function which needs to go through a class' types and identify a specific type. If I find that type, I want to cast it to the type that I know it is. But in the code below, the following case is failing:
BaseTableObjectList<BaseTableObject> obj = pi.GetValue(item, null) as BaseTableObjectList<BaseTableObject>;
Here is the code. Basically, I am making an iterator which returns certain properties. Why can't I cast?
foreach (PropertyInfo pi in item.GetType().GetProperties())
{
if (pi.PropertyType.BaseType == null) continue; // skip interfaces
if (!pi.PropertyType.BaseType.IsGenericType) continue; // only interested in childlists
Type[] types = pi.PropertyType.BaseType.GetGenericArguments();
// is my generic argument derived from baseObject?
if (typeof(BaseTableObject).IsAssignableFrom(types[0]))
{
// this is a child we want
log.Info(types[0].Name);
BaseTableObjectList<BaseTableObject> obj = pi.GetValue(item, null) as BaseTableObjectList<BaseTableObject>;
yield return obj;
}
}
Upvotes: 3
Views: 121
Reputation: 12366
Make sure that pi.GetValue(item, null).GetType()
is actually the type you want to cast to. It seems like it returns BaseTableObject
instead BaseTableObjectList<BaseTableObject>
If your class Company : BaseTableObject
and your CompanyList : BaseTableObjectList<Company>
then your result can be cast to BaseTableObjectList<BaseTableObject>
by using CompanyList.Cast<BaseTableObject>()
Edit2: From your comments, I think the following code will do the work.
BaseTableObjectList<BaseTableObject> obj = new BaseTableObjectList<BaseTableObject>((pi.GetValue(item, null) as System.Collections.IEnumerable).Cast<BaseTableObject>());
Upvotes: 2
Reputation: 7584
The problem you have I think is one of covariance, which only applies to interfaces. If you had a IBaseTableObjectList<out T> where T : BaseTableObject
the cast wouldn't fail. Covariance for generics is only supported on delegates and interfaces not on base classes:
http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx
In C#, variance is supported in the following scenarios:
- Covariance in arrays (since C# 1.0)
- Covariance and contravariance in delegates, also known as “method group variance” (since C# 2.0)
- Variance for generic type parameters in interfaces and delegates (since C# 4.0)
This is essentially the same problem is assigning a List<string>
to an IEnumerable<object>
which is one of the examples in the linked article.
Upvotes: 1