设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 2786|回复: 0
打印 上一主题 下一主题

【原创】System.Array类自动继承泛型接口

[复制链接]
跳转到指定楼层
1#
发表于 2014-2-24 11:28:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 faunus 于 2014-2-24 11:29 编辑

首先看一下Array的定义:

  1. public abstract class Array : ICloneable, IList, ICollection, IEnumerable
复制代码

并没有实现泛型接口
实际Array是支持这些泛型接口的:


  1. using System;
  2. using System.Collections.Generic;
  3. //using System.SZArrayHelper//无法调用
  4. class MyClass
  5. {
  6.     static void Main(string[] args)
  7.     {
  8.         int[] intArray = { 1, 2, 3, };
  9.         //类型测试
  10.         Console.WriteLine(intArray.GetType().ToString());//System.Int32[]
  11.         Console.WriteLine(intArray is IEnumerable<int>);//True
  12.         Console.WriteLine(intArray is ICollection<int>);//True
  13.         Console.WriteLine(intArray is IList<int>);//True
  14.         
  15.         //转换到接口
  16.         IEnumerable<int> ieT = intArray;
  17.         ICollection<int> icT = intArray;
  18.         IList<int> icL = intArray;
  19.         //IList接口部分//接口的定义中有
  20.         //intArray.Insert();//并没有实现
  21.         //intArray.Remove();//并没有实现
  22.         //intArray.RemoveAt();//并没有实现
  23.         //转化为接口后,就有定义
  24.         icL.Insert(0, 4);
  25.         //未处理的异常:  System.NotSupportedException: 集合的大小是固定的。
  26.         //在 System.SZArrayHelper.Insert[T](Int32 index, T value)
  27.         icL.Remove(1);
  28.         //未处理的异常:  System.NotSupportedException: 集合的大小是固定的。
  29.         //在 System.SZArrayHelper.Remove[T](T value)
  30.         icL.RemoveAt(1);
  31.         //未处理的异常:  System.NotSupportedException: 集合的大小是固定的。
  32.         //在 System.SZArrayHelper.RemoveAt[T](Int32 index)
  33.     }
  34. }
复制代码

通过实例测试,Array又确实是实现了这些接口的。
同样包括前面的老问题:
Array实现了:IList(包含Insert、Remove、RemoveAt)
Array没实现:Insert、Remove、RemoveAt
在转换为接口后会抛出:System.NotSupportedException异常。

感谢rightyeah朋友的工作,我引用如下:
我查过,Array类实现了IList所有的方法,
可以用ildasm查看mscorlib.dll,Array实现了
System.Collections.IList接口的 Add,Clear,Contains,IndexOf,Insert ,Remove ,RemoveAt ,get_Item,set_Item方法

注意:是ildasm中查看到的结果,不是对象浏览器中的结果。

再看一下MSDN中的重要声明:
http://msdn.microsoft.com/zh-cn/library/system.array.aspx

在 .NET Framework 2.0 版中,Array 类实现  System.Collections.Generic.IList <(Of <(T>)>)、 System.Collections.Generic.ICollection <(Of <(T>)>) 和  System.Collections.Generic.IEnumerable <(Of <(T>)>) 泛型接口。由于实现是在运行时提供给数组的,因而对于文档生成工具不可见。因此,泛型接口不会出现在 Array 类的声明语法中,也不会有关于只能通过将数组强制转换为泛型接口类型(显式接口实现)才可访问的接口成员的参考主题。将某一数组强制转换为这三种接口之一 时需要注意的关键一点是,添加、插入或移除元素的成员会引发  NotSupportedException。

同时我们还意外发现:
.net还藏了不少的私货
System.SZArrayHelper你用不了,
但MS可以,呵呵。




非泛型数且和泛型数组哪个更快点,
这个不想深入,只是引用一些网友现成的结果:

同一个数组泛型和非泛型时的Enumerator不同.
System.Array+SZArrayEnumerator
System.SZArrayHelper+SZGenericArrayEnumerator`1[System.Object]

用Reflector看他们的实现,大多数代码一样,唯一的区别是,
System.Array+SZArrayEnumerator.Current属性的实现:
return this._array.GetValue(this._index);

而System.SZArrayHelper+SZGenericArrayEnumerator`1[System.Object].Current属性的实现:
return this._array[this._index];

注意,前一个_array是Array类型的,后一个是object[]类型的.

也就是说,
[1]非泛型时,getvalue需要执行Array.GetValue()也就是下面这段额外的代码:

  1. <font color="#333333"><font face="Arial"><font style="font-size: 14.399999618530273px">public unsafe object GetValue(int index) { if (this.Rank != 1) { throw new ArgumentException(Environment.GetResourceString("Arg_Need1DArray")); } TypedReference reference = new TypedReference(); this.InternalGetReference((void*)&reference, 1, &index); return TypedReference.InternalToObject((void*)&reference); }</font></font></font>
复制代码
[2]而泛型直接一个索引就返回值了.

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-8 01:48 , Processed in 0.085601 second(s), 24 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表