泛型列表的集合

本文关键字:集合 列表 泛型 | 更新日期: 2023-09-27 18:18:52

我有一个函数需要遍历一个类的类型并识别一个特定的类型。如果我找到了那个类型,我想把它转换成我知道的类型。但是在下面的代码中,下面的情况是失败的:

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

泛型列表的集合

确保pi.GetValue(item, null).GetType()实际上是您想要转换的类型。看起来它返回的是BaseTableObject而不是BaseTableObjectList<BaseTableObject>

如果你的类Company : BaseTableObject和你的CompanyList : BaseTableObjectList<Company>,那么你的结果可以通过使用CompanyList.Cast<BaseTableObject>()转换为BaseTableObjectList<BaseTableObject>

编辑2:从你的评论来看,我认为下面的代码可以完成工作。

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

我认为你的问题是协方差之一,它只适用于接口。如果你有一个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>,这是链接文章中的一个例子。