在c#中,为什么我可以将接口强制转换为任何类型而不会出现编译器错误

本文关键字:类型 任何 错误 编译器 转换 为什么 我可以 接口 | 更新日期: 2023-09-27 17:57:33

考虑以下代码

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

即使ArrayList没有实现IDisposable,编译时也不会发出警告。

似乎可以将任何接口强制转换为不实现该接口的类。既然两者的类型在编译时都很明显,为什么编译器不对此进行验证?

在c#中,为什么我可以将接口强制转换为任何类型而不会出现编译器错误

它不会验证它,因为它可能是一个有效的强制转换。

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类,编译器可以做出更多的假设,并且它不需要检查每个路径就知道它的强制转换总是会失败,下面的代码将无法编译。

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
{
}
相关文章: