通用列表的集合

时间:2011-12-23 17:55:19

标签: c# reflection

我有一个需要通过类'类型并识别特定类型的函数。如果我找到那种类型,我想将它转换为我所知道的类型。但是在下面的代码中,以下情况失败了:

 BaseTableObjectList<BaseTableObject> obj = pi.GetValue(item, null) as BaseTableObjectList<BaseTableObject>;

这是代码。基本上,我正在创建一个返回某些属性的迭代器。我为什么不能演员?

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

2 个答案:

答案 0 :(得分:2)

确保pi.GetValue(item, null).GetType()实际上是您要投射到的类型。它似乎返回BaseTableObject而不是BaseTableObjectList<BaseTableObject>

如果您的班级Company : BaseTableObjectCompanyList : BaseTableObjectList<Company>,则可以使用BaseTableObjectList<BaseTableObject>

将您的结果投射到CompanyList.Cast<BaseTableObject>()

Edit2:从您的评论中,我认为以下代码将完成这项工作。

BaseTableObjectList<BaseTableObject> obj = new BaseTableObjectList<BaseTableObject>((pi.GetValue(item, null) as System.Collections.IEnumerable).Cast<BaseTableObject>());

答案 1 :(得分:1)

我认为你遇到的问题是协方差问题,它只适用于接口。如果你有IBaseTableObjectList<out T> where T : BaseTableObject,那么演员阵容不会失败。只有委托和接口不支持基类的泛型的协方差:

http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx

  

在C#中,以下情况支持方差:

     
      
  • 数组中的协方差(自C#1.0起)
  •   
  • 代表中的协方差和逆变,也称为“方法组差异”(自C#2.0起)
  •   
  • 接口和委托中的泛型类型参数的差异(自C#4.0起)
  •   

基本上同样的问题是将List<string>分配给IEnumerable<object>,这是链接文章中的一个示例。