Upcasting Generics

时间:2014-04-17 23:26:11

标签: c# generics casting

好的,我知道这是不可能的,但我想知道是否有人知道如何解决这个问题。

List<int> numberList = new List<int>();

List<object> objectList = (List<object>)numberList;

这会产生以下错误:

  

无法转换类型&#39; System.Collections.Generic.List {int}&#39;到&#39; System.Collections.Generic.List {object}&#39;

这是一个简单的例子,但这是我真正的问题。我有一个动态生成IQueryable{IGrouping{TKey, TElement}}实例的方法。但是,因为在我的情况下TKey是动态生成的,所以我只能向调用者返回IQueryable

我希望能够将IQueryable{IGrouping{dynamic, TElement}}返回给来电者。然而,编译器抱怨是因为就像在我的第一个例子中,它的转换TKey作为对象(对于dynamic),并且不允许我这样投射它。有没有办法解决这个问题?

更新

以下是我试图解决的更接近的例子:

List<int> testList = new List<int>();

var qry = new EnumerableQuery<int>( testList );

var objectQry = (IQueryable<object>)qry;

虽然此示例不会产生编译时错误,但在尝试运行它时会产生转换异常。出于某种原因,即使IQuerable是协变的(感谢Servy对此有所评论),一旦我引入了EnumerableQuery等实现类,它就会失败。

2 个答案:

答案 0 :(得分:3)

试试这个。

List<int> numberList = new List<int>();
List<object> objectList = numberList.Cast<object>().ToList();

Enumerable.Cast<T>

  

将IEnumerable的元素转换为指定的类型。

答案 1 :(得分:2)

您需要构建每个新字典的副本,因为字典和列表与其任何通用参数不相关。

(密钥也通过Keys属性输出,以及对的序列本身,所以即使IDictionary<TKey, TValue>也不能与TKey协变。)

您可以使用Select将每个对象映射到新对象:

List<Dictionary<int, string>> listOfDicts = new List<Dictionary<int, string>>();
List<Dictionary<object, string>> newList = listOfDicts.Select(dic =>
        dic.ToDictionary(pair => (object)pair.Key, pair => pair.Value))
    .ToList();
另一方面

IQueryable<T> 协变,就像IGrouping一样,所以你可以构建这些类型的接口:

IQueryable<IGrouping<dynamic, int>> query = null;
IQueryable<IGrouping<object, int>> otherQuery = query;

编译并运行得很好。