C# 中所有数组都实现哪些接口?

发布于 2024-10-08 00:25:25 字数 348 浏览 11 评论 0原文

作为一名新的 .NET 3.5 程序员,我开始学习 LINQ,我发现了一些我以前没有注意到的非常基本的东西:

这本书声称每个数组都实现 IEnumerable (显然,否则我们无法不要在数组上使用 LINQ to 对象...)。当我看到这个时,我心想我从来没有真正考虑过这一点,我问自己所有数组还实现了什么 - 所以我检查了 使用对象浏览器的 System.Array(因为它是 CLR 中每个数组的基类),令我惊讶的是,它没有实现 IEnumerable

所以我的问题是:定义在哪里?我的意思是,我如何才能准确地知道每个数组实现了哪些接口?

As a new .NET 3.5 programmer, I started to learn LINQ and I found something pretty basic that I haven't noticed before:

The book claims every array implements IEnumerable<T> (obviously, otherwise we couldn't use LINQ to objects on arrays...). When I saw this, I thought to myself that I never really thought about that, and I asked myself what else all arrays implement - so I examined
System.Array using the object browser (since it's the base class for every array in the CLR) and, to my surprise, it doesn't implement IEnumerable<T>.

So my question is: where is the definition? I mean, how can I tell exactly which interfaces every array implements?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风吹过旳痕迹 2024-10-15 00:25:25

来自文档(强调我的):

[...] Array 类实现 System.Collections.Generic.IListSystem.Collections.Generic.ICollection,以及System.Collections.Generic.IEnumerable 通用接口。 这些实现在运行时提供给数组,因此对文档构建工具不可见。

编辑: 正如 Jb Evain 在他的评论中指出的那样,只有向量(一个维数组)实现通用接口。至于为什么多维数组不实现通用接口,我不太确定,因为它们确实实现了非通用对应项(请参阅下面的类声明)。

System.Array 类(即 every 数组)也实现了这些非泛型接口:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable

From the documentation (emphasis mine):

[...] the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools.

EDIT: as Jb Evain points out in his comment, only vectors (one-dimensional arrays) implement the generic interfaces. As to why multi-dimensional arrays don't implement the generic interfaces, I'm not quite sure since they do implement the non-generic counterparts (see the class declaration below).

The System.Array class (i.e. every array) also implements these non-generic interfaces:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
残月升风 2024-10-15 00:25:25

您可以使用一个小代码片段凭经验找到问题的答案:

foreach (var type in (new int[0]).GetType().GetInterfaces())
    Console.WriteLine(type);

运行上述代码片段将产生以下输出(在 .NET 4.0 上):(

System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]

`1 表示)

.NET 4.5.NET Standard 1.0 及更高版本)之后,有两个附加接口:

System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

You can find the answer to your question empirically using a small code snippet:

foreach (var type in (new int[0]).GetType().GetInterfaces())
    Console.WriteLine(type);

Running the above snippet would result in the following output (on .NET 4.0):

System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]

(`1 means <T>)

After .NET 4.5 (.NET Standard 1.0 and later), there's two additional interfaces:

System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
陈年往事 2024-10-15 00:25:25

从 .NET 4.5 开始,数组还实现了接口 <代码>System.Collections.Generic.IReadOnlyListSystem.Collections.Generic.IReadOnlyCollection

因此,当使用.NET 4.5时,数组实现的接口的完整列表变为(使用Hosam Aly的回答):

System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

奇怪的是,似乎忘记更新 MSDN 上的 文档 提一下这两个接口。

Starting with .NET 4.5, arrays also implement the interfaces System.Collections.Generic.IReadOnlyList<T> and System.Collections.Generic.IReadOnlyCollection<T>.

Thus, when using .NET 4.5, the complete list of interfaces implemented by arrays becomes (obtained using the method presented in Hosam Aly's answer):

System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

Strangely, it seems that it was forgotten to update the documentation on MSDN to mention these two interfaces.

云醉月微眠 2024-10-15 00:25:25

小心地在数组接口上,他们可能会实现它们,但实际上他们并没有真正这样做......仔细研究以下代码:

            var x = new int[] { 1, 2, 3, 4, 5 };
        var y = x as IList<int>;
        Console.WriteLine("The IList:" + string.Join(",", y));
        try
        {
            y.RemoveAt(1);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        Console.WriteLine(string.Join(",", y));

它会产生以下输出:
结果

因此解析有效,但并非所有内容都受支持,从固定长度集合的角度来看,这是正确的,但完全错误如果你真的相信这是一个列表。 SOLID 遵循里氏原则:(。

对于快速测试会有所帮助。

Carefully on array interfaces, they may implement them but actually they don't really do this... Take a loon on the following code:

            var x = new int[] { 1, 2, 3, 4, 5 };
        var y = x as IList<int>;
        Console.WriteLine("The IList:" + string.Join(",", y));
        try
        {
            y.RemoveAt(1);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        Console.WriteLine(string.Join(",", y));

It produces the following output:
result

So parsing works but not everything is supported which is correct from fixed length collection perspective but quite wrong if you really believe that it is a list. There goes Liskov principle from SOLID :(.

For testing fast this will help.

夕色琉璃 2024-10-15 00:25:25

我在 Array 的 SZArrayHelper 嵌套类中找到了 IList、ICollection、IEnumerable 的实现。

但我必须警告您 - 在那里您会发现更多问题...

参考

之后我只得到了一个 - There_is_no_array ;)

I have found the implementation of the IList<T>, ICollection<T>, IEnumerable<T> in the SZArrayHelper nested class of the Array.

But i have to warn you - there you will find much more questions...

The refference

After that i got only one - there_is_no_array ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文