在c#中为什么我可以在没有编译器错误的情况下将接口转换为任何类型

时间:2016-07-18 14:06:54

标签: c# interface

考虑以下代码

IDisposable foo = <something>;
ArrayList bar = (ArrayList)foo;

即使ArrayList没有实现IDisposable,也会在没有警告的情况下进行编译。

您似乎可以将任何接口强制转换为未实现该接口的类。由于两者的类型在编译时是显而易见的,为什么编译器不验证这个?

1 个答案:

答案 0 :(得分:1)

它不会验证它,因为它可能是有效的演员。

public class Foo : ArrayList, IDisposable
{
   ...
}
public class Bar : IDisposable
{
   ...
}

Random rand = new Random();
public IDisposable SomtimesGetArrayList()
{
    if(rand.Next(0,4) == 0)
        return new Bar();

    return new Foo();
}

//Elsewhere
IDisposable foo = SomtimesGetArrayList();
ArrayList bar = (ArrayList)foo;

SomtimesGetArrayList的4次调用中有3次将返回一个可以成功投射的对象。编译器检查每个代码路径并确保每种可能的方式都可以生成一个对象,这是一个太多的处理工作。

但是,如果您有一个sealed类,编译器可以做出更多假设,并且不需要检查每个路径以确定转换将始终失败,以下代码will fail to compile。< / p>

using System;

public class Program
{
    public static void Main()
    {
        IDisposable foo = new Foo();
        Bar bar = (Bar)foo;
    }
}

public class Foo : IDisposable 
{
    public void Dispose()
    {
    }
}

public sealed class Bar
{
}