0

假设我有两节课,

class A
{
}

class B : A
{
}

我有一个接受foo类型参数的方法IEnumerable<A>;

void AMethod(IEnumerable<A> foo)
{
}

而是传入一个 type 的值IEnumerable<B>

AMethod(new[] { new B() });

这会编译并执行,尽管在执行时foo已隐式转换为IEnumerable<B>. 现在假设我IEnumerable<B>包含 A 类型的对象(我认为它们是混合的还是相同的并不重要)。当我打电话时,foo.Any()我得到一个例外:

无法将“A”类型的对象转换为“B”类型

我知道我不能将基类转换为子类,但这不是我想要做的(事实上,在执行的这一点上,我什至不在乎它是什么类型)。我猜 LINQ 本质上是在尝试进行这种转换,可能是基于footype的事实IEnumerable<B>。所以,似乎我需要编写两个单独的方法,一个是处理IEnumerable<A>,一个是处理IEnumerable<B>。我不明白为什么我需要这样做。有什么想法吗?

编辑:

正在进行一些动态的铸造和转换,设法吐出一个充满IEnumerable<B>“A”的人,直到现在我认为这也是不可能的。我会尽力翻译导致此方法调用的情况:

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);
4

1 回答 1

0

AnIEnumerable<B>不能包含类型的对象,A因为 andA不是B.

我可以写这段代码,

IEnumerable<B> dodgy = (new[] { new A() }).Cast<B>();

它会编译,尽管显然是错误的。编译器假设我知道我在做什么。请记住,IEnumerable尚未评估序列中的任何项目。

当我编写评估成员的代码时,dodgy我得到异常,因为 anA不是 aB并且不支持转换为B.

我可以写

IEnumerable<A> fine = new[] { new B() };

不需要强制转换,一切正常,因为 aBA.


如果我做,

var hungrilyDodgy = (new[] { new A() }).Cast<B>().ToList();

Tolist()强制对 进行枚举和评估IEnumerable,因此将更快地抛出异常。

于 2013-05-01T14:41:36.497 回答