gpt4 book ai didi

c# - 为什么我可以放弃 IList 的不变性?

转载 作者:太空狗 更新时间:2023-10-29 23:02:14 25 4
gpt4 key购买 nike

目前,我正在为我的同事准备 C# 中新的通用变体特性的演示。简而言之,我写了以下几行:

IList<Form> formsList = new List<Form> { new Form(), new Form() };
IList<Control> controlsList = formsList;

是的,这当然是不可能的,因为 IList(Of T) 是不变的(至少我是这么认为的)。编译器告诉我:

Cannot implicitly convert type System.Collections.Generic.IList<System.Windows.Forms.Form> to System.Collections.Generic.IList<System.Windows.Forms.Control>. An explicit conversion exists (are you missing a cast?)

嗯,这是否意味着我可以强制进行显式转换?我刚刚试过了:

IList<Form> formsList = new List<Form> { new Form(), new Form() };
IList<Control> controlsList = (IList<Control>)formsList;

然后……它编译了!这是否意味着我可以放弃不变性? - 至少编译器对此没有问题,但我只是将之前的编译时错误转换为运行时错误:

Unable to cast object of type 'System.Collections.Generic.List`1[System.Windows.Forms.Form]' to type 'System.Collections.Generic.IList`1[System.Windows.Forms.Control]'.

我的问题:为什么我可以转换 IList<T> 的不变性(或任何其他关于我的实验的不变接口(interface))离开?我真的放弃了不变性,还是这里发生了什么样的转换(因为 IList(Of Form)IList(Of Control) 完全不相关)?这是我不知道的 C# 黑暗角落吗?

最佳答案

本质上,一个类型可以实现IList<Control> 以及 IList<Form>所以转换可能成功 - 所以编译器暂时让它通过(另外:它可能在这里更聪明并产生警告,因为它知道引用对象的具体类型,但不是。我认为产生编译器错误是不合适的,因为它不是实现新接口(interface)的类型的重大更改。

作为这种类型的一个例子:

public class EvilList : IList<Form>, IList<Control> { ... }

运行时发生的只是 CLR 类型检查。您看到的异常表示此操作失败。

为转换生成的 IL 是:

castclass [mscorlib]System.Collections.Generic.IList`1<class [System.Windows.Forms]System.Windows.Forms.Control>

来自 MSDN :

The castclass instruction attempts to cast the object reference (type O) atop the stack to a specified class. The new class is specified by a metadata token indicating the desired class. If the class of the object on the top of the stack does not implement the new class (assuming the new class is an interface) and is not a derived class of the new class then an InvalidCastException is thrown. If the object reference is a null reference, castclass succeeds and returns the new object as a null reference.

InvalidCastException is thrown if obj cannot be cast to class.

关于c# - 为什么我可以放弃 IList<T> 的不变性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7907391/

25 4 0