栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

C#中的数组如何部分实现IList?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C#中的数组如何部分实现IList?

根据汉斯的答案的新答案

感谢汉斯给出的答案,我们可以看到实现比我们想象的要复杂一些。编译器和CLR都 非常努力
地给人以数组类型实现的印象

IList<T>
-但是数组差异使这一点变得棘手。与Hans的答案相反,数组类型(无论
单维还是从零开始)确实可以直接实现泛型集合,因为任何特定数组的类型都不
System.Array
-这只是数组的 基本
类型。如果您问一个数组类型它支持什么接口,它包括通用类型:


foreach (var type in typeof(int[]).GetInterfaces()){    Console.WriteLine(type);}

输出:

System.ICloneableSystem.Collections.IListSystem.Collections.ICollectionSystem.Collections.IEnumerableSystem.Collections.IStructuralComparableSystem.Collections.IStructuralEquatableSystem.Collections.Generic.IList`1[System.Int32]System.Collections.Generic.ICollection`1[System.Int32]System.Collections.Generic.IEnumerable`1[System.Int32]

对于一维,从零开始的数组,就 语言
而言,该数组确实也可以实现

IList<T>
。C#规范的第12.1.2节是这样说的。因此,无论底层实现如何执行,语言都必须像实现其他接口一样实现 行为
。从这个角度来看,该接口 在某些成员被明确实现的情况下实现的(例如)。对于发生的事情,这是最佳的 语言 解释。
T[]``IList<T>

Count

请注意,这仅适用于一维数组(以及从零开始的数组,而不是C#,因为一种语言说了有关非从零开始的数组)。

T[,]
没有 实现
IList<T>

从CLR的角度来看,有些事情正在发生。您无法获取通用接口类型的接口映射。例如:

typeof(int[]).GetInterfaceMap(typeof(ICollection<int>))

给出以下例外:

Unhandled Exception: System.ArgumentException: Interface maps for genericinterfaces on arrays cannot be retrived.

那为什么奇怪呢?好吧,我相信这确实是由于数组协方差引起的,这是类型系统IMO中的疣。即使

IList<T>

协变(和不能安全),数组协方差允许这种工作:

string[] strings = { "a", "b", "c" };IList<object> objects = strings;

看起来 好像是

typeof(string[])
器物
IList<object>
,实际上不是。

CLI规范(ECMA-335)分区1(第8.7.1节)具有以下内容:

签名类型T与签名类型U兼容-并且仅当以下至少一项成立时

T是从零开始的rank-1数组

V[]
,并且
U
IList<W>
,并且V是与W兼容的数组元素。

(它实际上没有提及

ICollection<W>
IEnumerable<W>
我认为是规范中的错误。)

对于非差异性,CLI规范与语言规范直接匹配。从分区1的8.9.1节开始:

此外,创建的元素类型为T的向量将实现interface

System.Collections.Generic.IList<U>
,其中U:=T。(第8.7节)

向量 是基数为零的一维数组。)

现在,在条款 实施细则
,明确了CLR做一些时髦的映射,以保持分配兼容性这里:当

string[]
被要求执行
ICollection<object>.Count
,它不能处理,在
相当 正常的方式。这算作显式接口实现吗?我认为以这种方式进行处理是合理的,因为除非您直接要求接口映射,否则从语言角度来看,它始终 会以
这种方式运行。

ICollection.Count

到目前为止,我已经讨论了泛型接口,但是接下来是

ICollection
具有其
Count
属性的非泛型。这次我们 可以
获取接口映射,并且实际上该接口是直接由实现的
System.Array
。该
ICollection.Count
属性实现的文档
Array
指出,它是通过显式接口实现实现的。

如果有人能想到这种显式接口实现与“常规”显式接口实现不同的方法,我很乐意进一步研究它。

关于显式接口实现的旧答案

尽管上述操作由于数组知识而变得更加复杂,但是您仍然 可以 通过显式接口实现来执行具有相同 可见 效果的操作。

这是一个简单的独立示例:

public interface IFoo{    void M1();    void M2();}public class Foo : IFoo{    // Explicit interface implementation    void IFoo.M1() {}    // Implicit interface implementation    public void M2() {}}class Test    {    static void Main()    {        Foo foo = new Foo();        foo.M1(); // Compile-time failure        foo.M2(); // Fine        IFoo ifoo = foo;        ifoo.M1(); // Fine        ifoo.M2(); // Fine    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/391695.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号