为什么这个多态操作会编译?

时间:2014-04-02 18:42:13

标签: c# .net polymorphism

我不明白为什么以下代码编译 -

ICollection selecteditems = iselect.Snapshot();
foreach (Content c in selecteditems)
    ....

正如您所料,Snapshot()会返回Content个集合,但ICollection不包含类型信息,更不用说Content类型了。程序的这个范围不应该知道Content,为什么要编译?

2 个答案:

答案 0 :(得分:3)

因为您发布的代码与以下代码相同

ICollection selecteditems = iselect.Snapshot();

foreach (object temp in selecteditems)
{
    Content c = (Content)temp; //This is fine at compile-time but fails at run-time.
    ...
}

object可投放到任何其他对象,因为ICollection只有IEnumerable而不是IEnumerable<T>,因此临时类型将为object。尝试使用实现IEnumerable<T>的密封类,您将看到编译时错误。

sealed class Foo : IEnumerable<Foo>
{
    IEnumerator<Foo> GetEnumerator()
    {
        throw new NotImplmentedException();
    }

    object IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

class Bar
{
}

上会出现编译时错误
IEnumerable<Foo> selecteditems = iselect.Snapshot();
foreach (Bar c in selecteditems) //Compile time error.
{
    ...

这相当于

IEnumerable<Foo> selecteditems = iselect.Snapshot();
foreach (Foo temp in selecteditems)
{
    Bar c = (Bar)temp; //This cast fails at compile-time.
    ...
}

答案 1 :(得分:0)

ICollection枚举器将返回object的枚举。在运行时期间,它将尝试将object实例强制转换为Content实例。如果它可以,一切都很好,如果不能,则抛出类型转换异常。