CLR Via C# 3rd 阅读摘要 -- Chapter 16 - Arrays

Initializing Array Elements

1. var names = new[] {"Aidan", "Grant", null}; 编译器正常编译,因为可以推断names是string[];

2. var names = new[] {"Aidan", "Grant", 123}; 编译器会产生编译错误;

3. var names = {"Aidan", "Grant"};编译器也会产生编译错误; 

4. var kids = new[] {new {Name = "Aidan"}, new {Name = "Grant"}};这会生成匿名类型的数组。

Casting Arrays

1. Array.Copy可以从一个数组拷贝到另外一个数组,就像C的memmove。Copy还可以进行数组转换:

装箱值类型到引用类型,比如Int32[]到object[];

拆箱引用类型到值类型,比如object[]到Int32[];

拓宽原生类型,比如Int32[]到Double[];

降解元素,比如object[]到IFormattable[]。

2. System.Buffer.BlockCopy要比Array.Copy快的多,但是BlockCopy只支持原生类型;

3. System.Array.ConstrainedCopy提供可靠的数组拷贝操作,该方法可以用在CER(Constrained Execution Region)中,要求元数组和目的数组同类型;

4. 创建接口的数组,比如:IIterface[] interfaces = new IInterface[10];是可以的。  

All Arrays Are Implicitly Derived from System.Array

1. 所有的数组隐式的从System.Array继承。

All Arrays Implicitly Implement IEnumerable, ICollection, and IList

1. 所有的数组隐式的实现了IEnumerable,ICollection,IList接口; 

2. CLR没有给System.Array实现IEnumerable<T>, ICollection<T>, IList<T>泛型接口,但是当一个一维零基的数组类型建立时,CLR自动标记这个数组类型实现这三个泛型接口,并且实现了该数组类型的所有基类型(引用类型)的这三个泛型接口;

3. 如果是值类型,CLR只实现该类型的IEnumerable<T>, ICollection<T>, IList<T>的泛型接口,而不实现基类型。

Passing and Returning Arrays

1. 当数组作为参数或者返回值时,传递的是引用。

Creating Non-Zero-Lower Bound Arrays

1. Array.CreateInstance(Type type, Int32[] lenths, Int32[] lowerBounds)可以创建一个非零基的多维数组;

2. Array.GetLowerBound()和Array.GetUpperBound()可以获得数组的上下边界。

Array Access Performance

1. 在循环中调用Array.Length成本比较高;

2. 访问非零基数组和多维数组要比一维的零基数组慢很多;

3. 数组的数组(jagged数组Int32[][])比规则的多维数组(Int32[,])要快;

4. unsafe的方式操作数组具有更高的性能和灵活性,但是要注意时机,下面三种情形要注意:

  • 代码可读性复杂度增加,使用了fixed关键字并执行内存地址计算;
  • 如果地址计算错误,那么会出现越界,产生安全隐患;
  • CLR禁止不安全代码运行在受限环境下(比如SilverLight)。

Unsafe Array Access and Fixed-Size Array

1. 不安全数组的强大之处在于可以访问:

  • 驻留在托管堆上的数组元素;
  • 驻留在非托管堆上的数组元素;
  • 驻留在线程栈上的数组元素。

2. 使用C#的stackalloc(类似与C的alloc)可以在线程栈上分配数组;

3. stackalloc可以用来创建一维零基的值类型数组。而且,大小有1M的限制。需要/unsafe编译开关;

4. 直接嵌入一个数组到结构体中需要满足几个条件:

  • 类型必须是一个结构体(值类型);
  • 字段和定义的结构体必须有unsafe关键字;
  • 该结构体的数组字段必须有fixed关键字;
  • 数组必须是一维零基的;
  • 数组的元素类型必须是下列之一:Boolean, Char, Byte, SByte, Int32, UInt32, Int64, UInt64, Single, Double。 

本章小结

   本章讲述的是数组的概念。CLR可以支持多种形式的数组。首先讲了如何初始化一个数组,然后讲了如何转换数组以及Array.Copy的用途和局限性,阐明了数组的一些潜在特性,然后讲了如何创建一个多维非零基的数组,并且比较了不同数组在访问性能上的差异,最后重点解释了不安全数组的特性和使用要点。 

 

posted @ 2010-04-19 17:40  bengxia  阅读(292)  评论(0编辑  收藏  举报
无觅相关文章插件,快速提升流量