假设我有两个班级,
class A
{
}
class B : A
{
}
我有一个接受foo
IEnumerable<A>;
的方法
void AMethod(IEnumerable<A> foo)
{
}
,而是传入IEnumerable<B>
类型的值。
AMethod(new[] { new B() });
这会编译并执行,但执行foo
时已隐式转换为IEnumerable<B>
。现在让我们说我的IEnumerable<B>
包含A类对象(我不相信它们是混合还是全部相同)。当我致电foo.Any()
时,我得到一个例外:
无法将类型为'A'的对象强制转换为'B'
我理解我无法将基类转换为子类,但这不是我想要做的事情(实际上在执行的这一点上,我甚至不关心它是什么类型)。我猜LINQ本身就是在试图进行这种转换,可能是基于foo
类型为IEnumerable<B>
的事实。所以,似乎我需要编写两个单独的方法,一个处理IEnumerable<A>
,另一个处理IEnumerable<B>
。我不明白为什么我需要这样做。有什么想法吗?
编辑:
有一些动态的转换和转换正在设法吐出一个填充了'A'的IEnumerable<B>
,直到现在我认为这也是不可能的。我将尽力翻译此方法调用之前发生的事情:
protected void SetDynamicData(dynamic data)
{
_data = data;
IsB = typeof(IBInterface).IsAssignableFrom(_data.DataType);
}
...
var foo = IsB ? _data.Cast<B>() : data.Cast<A>();
return BuildJqGridData<A, B, int>(gridModel, foo);
答案 0 :(得分:0)
IEnumerable<B>
不能包含A
类型的对象,因为A
不是B
。
我可以写这段代码,
IEnumerable<B> dodgy = (new[] { new A() }).Cast<B>();
它会编译,尽管显然是错误的。编译器假设我知道我在做什么。请记住,IEnumerable
序列中的任何项目尚未进行评估。
当我编写评估dodgy
成员的代码时,由于A
不是B
且不支持转换为B
,我会收到异常。
我可以写
IEnumerable<A> fine = new[] { new B() };
不需要强制转换,一切正常,因为B
是A
。
如果我这样做,
var hungrilyDodgy = (new[] { new A() }).Cast<B>().ToList();
Tolist()
将强制枚举和评估IEnumerable
,因此会更快地抛出异常。