C#数组基础

这两天看了<CLR via C#>的第16章,数组部分,就将里面的给记录一边,方法日后查询。


所有的数据继承自System.Array抽象类,后者派生自System.Object类;

一、初始化
int[] integers = new int[10]  //在托管堆上分配容纳10个未装箱的int32所需的内存块;
control[] controls = new control[10];  //在托管堆上分配容纳10个control的引用 需要的空间,每个control初始化为null;

二维数组:
Double[,] ds = new Double[10,20]
交错数组:
Double[][] ds = new Double[10][]; //创建10个指向double[]数组的引用;


二、数组类型转换:
    两个数组类型必须维数相同,而且从源类型到目标类型必须存在一个隐式或显式的转换 ;但是CLR不允许将值类型元素的数组转型为其他任何类型;

三、数据复制:
1)、Array.Copy方法:
    将元素从一个数组复制到另一个数组,并且能够处理内存的重叠区域;但是只是进行浅复制;在复制时也进行必要的类型转化与装(拆)箱;
2)、System.Buffer.BlockCopy方法:
    速度快,只支持基元类型;
    方法的Int32参数代表的是数组中的字节偏移量,而非元素索引;即它实现的是按位兼容的形式进行复制;
按位兼容:指类型在托管堆与非托管堆上的内存上有相同的表示;
3)、System.Array.ConstrainedCopy方法:
    保证在不破坏目标数组中的数据的前提下完成复制,或者是抛出一个异常。
    它要求源数组类型要么与目标数据类型相同,要么派生自目标数据的元素类型。
    它不执行任何装箱、拆箱或向下类型转换(从基类到派生类)。

System.Array继续了IEnumerable,ICollection,IList接口,因为这些接口将所有元素视为Object,而没有实现这些接口的泛型类型;
而在0基1维的数据的创建时,实现相应类型的IEnumerable<T>,ICollection<T>,IList<T>接口;
如果数据包含值类型的元素,则数组类型不会为元素的基类型实现接口;
示例:
Object
    Array
        Object[]
            Stream[]
                FileStream[]
则FileStream[] fsArray; 这条语句执行时,将会实现:IEnumerable(ICollection,IList)<FileStream(Stream,Object)>这些类型;

但是执行如下的代码:
DateTime[] dtArray时;
只会实现:IEnumerable(ICollection,IList)<DateTime>这些类型,而不会为DateTime的基类型实现;
这是因为值类型数组与引用类型数组的内存布局不同。


四、创建下限非零的数组:
Int32 lowerBounds = {2005,1}
Int32 lengths = {5,4}
Decimal[,] qrArray = (Decimal[,[)Array.CreateInstance(typeof(Decimal), lengths, lowerBounds); 

五、访问数组的性能
访问一维0基数组比访问非0基一维或多维数组快。原因:
    1)、特殊的IL指令对0维数组进行优化,导致JIT编译器生成优化代码;
示例:
    int32[] a = new Int32[5]; 
    for(Int32 index = 0; index<a.Length; index++){
        //op
    }
在此有两个优化:
    其一:对数据Length属性的访问(这里实际上是执行GetLength的方法调用),JIT对0基一维数据只执行一次,并缓存在本地的临时变量中;
    其二:JIT在执行for循环的访问时,会先判断所有访问的数据是否在数组的有效范围之内。如
在执行循环时,先判断(0>=a.GetLowerBound(0)) && ((Length-1)<=a.GetUpperBound(0))。这个检查出现在循环之前,如果在数组的有效范围之内,JIT将不会在循环内部生成代码验证每一次数组访问都在有效范围之内。

    为增强性能,可能考虑用交错数组代替多维数组;
从访问的角度看,多维数组比交错数组慢;但是从创建与初始化角度看:由于创建交错数据时,要求在堆上为每一堆分配一个对象,这造成垃圾回收器的周期性活动。因此,如果是创建一个”多维数组“,且不会频繁访问,采用多维数组;反而采用交错数组;

六、不安全数组访问
    数据的性能主要在于:堆上分配内存。
    可通过实现在线程栈上分配,在每次方法返回时将自动释放内存,因此,不能将此数组指针传给大多数FCL的方法。实现方法:
        unsafe{
            Char *pc = stackalloc Char[10]; 
    }

可在unsafe结构中包含数据的类型满足如下要求:
    类型必须是结构(值类型);不能在引用 类型中嵌入数組;
    字段或其定义结构必须用unsafe关键字标记;
    数据字段必须用fixed关键字标记;
    数组必须是一维0基的;
    数组的类型可以是:Boolean,Char,Sbyte,Byte,int16,int32,uint16,uint32,int64,uint64,Single, Double.
示例:
    unsafe struct CharArray{
        public fixed Char Characters[20]; 
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值