【发布时间】:2011-06-29 18:10:39
【问题描述】:
我有以下几点:
foreach (ItemOption itemOption in p.Items.Select(e => e.ItemOption).GroupBy(e => e.Id))
{ // do some work on itemoptions }
这编译。 但是在运行时我得到一个 Invalid Cast 异常:
无法将“Grouping[System.String,MyNameSpace.ItemOption]”类型的对象转换为“MyNameSpace.ItemOption”类型。
如果我将代码更改为,例如一个字符串作为项目的类型:
foreach (String itemOption in p.Items.Select(e => e.ItemOption).GroupBy(e => e.Id))
{ // do some work on itemoptions }
然后编译器告诉我类型不兼容。
为什么编译器没有在第一个代码块中标记类型不兼容?
我做了一些进一步的调查,发现,给定以下代码:
var foo = p.Items.Select(e => e.ItemOption).GroupBy(e => e.Id));
Type singleElementType = foo.ElementAt(0).GetType();
singleElementType 是:
System.Linq.Lookup`2+Grouping[System.String, MyNamespace.ItemOption]
更新 根据答案,我整理了一个更简单的案例来证明这个问题
给定对象:
interface IMyObj
{
string Id;
}
class MyObj : IMyObj
{
public string Id;
public MyObj2 cg;
}
class MyObj2
{
}
这将在编译时失败
IEnumerable<MyObj> compileTimeFailList = new List<MyObj>()
foreach (MyObj2 myObj2 in compileTimeFailList.Where(x => x.Id != null))
{
这将在运行时失败
IEnumerable<IMyObj> runtimeFailList = new List<IMyObj>();
foreach (MyObj2 myObj2 in runtimeFailList.Where(x => x.Id != null))
{
原因是runtimeFailList 中的对象可能会扩展 MyObj2,这无法由编译器确定。
【问题讨论】: