C# 强制转换问题

3

我有这段代码:

myDataGrid 是传递给此方法的对象。我知道它是不同类型的OvserveableCollection

我需要做的就是将该对象转换为 OvserveableCollection<T> (它实现了IEnumerable接口)。

//get element's type
Type entryType = (myDataGrid as IEnumerable).AsQueryable().ElementType; 

foreach (var item in (IEnumerable<entryType>)myDataGrid)
{}

但编译器不知道循环头中的 entryType。为什么?

3个回答

5
除非使用反射(MakeGenericMethod() / MakeGenericType()),否则不能将运行时Type实例用作泛型类型参数。但是我怀疑这样做也没有帮助!在这种情况下,可以使用非泛型的IEnumerable(没有)API,或者转换为已知接口/子类,或者作为最后一招使用dynamic进行鸭式辨型。
您也可以使用MakeGenericMethod()等方法,但这更加复杂,而且几乎肯定会更慢。
例如:
foreach(object item in (IEnumerable)myDataGrid)
{
     // tada!
}

还有一个技巧是使用dynamic来调用泛型代码:

public void Iterate<T>(IEnumerable<T> data)
{
     foreach(T item in data) {...}
}
...
dynamic evil = myDataGrid;
Iterate(evil);

我不知道新的“dynamic”类型。是的,它很邪恶,因此我认为我会喜欢它。一旦成为脚本兔子,永远是黑客。感谢鱼儿;-) - corlettk

4
您正在尝试将Type变量用作通用类型的类型参数。通用类型不是这样工作的 - 您必须使用编译时类型作为类型参数(如果您在泛型方法中执行此操作,则该编译时类型可以是类型参数本身)。
但是,不知道更多关于您的要求,很难建议您如何更改代码 - 您需要对这些项做什么?

我需要通过迭代ObserveableCollection来读取每个元素中的数据。 - Tony
1
@Tony:你可以只使用“object”来完成这个任务,那么你为什么需要更为具体的编译时类型呢? - Jon Skeet

1

你不能将类型转换为 "运行时类型" ... 为了 "编写" 实际实现该转换的指令,编译器需要Type... 这实际上只是意味着在编译时必须知道Type。

我发现绕过这个限制的唯一方法是使用代码生成器(某种类型的)来 "手动" 生成执行转换的IL指令。 如果我们不了解您的实际要求(和限制),很难建议什么。

祝福你。 Keith.


是啊...不幸的是,我正在忙着将我们的应用程序升级到3.5版本,因为当我们开始这轮疯狂时,4.0版本还没有发布...唉。 - corlettk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接