MyException - 我的异常网
当前位置:我的异常网» C# » <NET CLR via c# 第4版>札记 第16章 数组

<NET CLR via c# 第4版>札记 第16章 数组

www.MyException.Cn  网友分享于:2013-08-22  浏览:0次
<NET CLR via c# 第4版>笔记 第16章 数组
        //创建一个一维数组
        int[] myIntegers;           //声明一个数组引用
        myIntegers = new int[100];  //创建含有100个int的数组

        //创建一个二维数组
        double[,] myDoubles = new double[10, 20];

        //创建一个三维数组
        string[,,] myStrings = new string[5, 3, 10];

        //创建交错数组
        Point[][] myPolygons = new Point[3][];
        myPolygons[0] = new Point[10];
        myPolygons[1] = new Point[20];
        myPolygons[2] = new Point[30];
  • 0基一维数组的性能是最佳的.因为可以使用一些特殊的IL指令.

16.1 初始化数组元素

    // 1) 利用c#的隐式类型的局部变量功能:
    var names1 = new string[] { "Alidan", "Grant" };

    // 2) 利用C#的隐式类型的局部变量和隐式类型的数组功能:
    var names2 = new[] { "Alidan", "Grant", null };

    // 3) 额外的语法奖励(这里不能用var)
    string[] names3 = { "Alidan", "Grant" };

    // 4) 使用C#的隐式类型的局部变量\隐式类型的数组和匿名类型功能:
    var kids = new[] { new { Name = "Aidan" }, new { Name = "Grant" } };
    foreach (var kid in kids)
        Console.WriteLine(kid.Name);

16.2 数组转型

  • 元素为引用类型的数组,如果维数相同,且元素源类型到目标类型存在隐式或显式转换,CLR 允许将数组元素从一种类型转型另一种.
  • CLR不允许将值类型元素的数组转型为其他任何类型,不过可用 Array.Copy 方法来模拟.
    //创建二维 FileStream 数组
    FileStream[,] fs2dim = new FileStream[5, 10];
    //隐式转型为二维 Object 数组
    object[,] o2dim = fs2dim;
    //显示转型为二维 Stream 数组
    Stream[,] s2dim = (Stream[,])o2dim;


    //创建一维 Int32 数组(元素是值类型)
    int[] ildim = new int[5];
    //下面的代码创建元素为引用类型的数组,
    //每个元素都是对已装箱 Int32 的引用
    object[] obldim = new object[ildim.Length];
    Array.Copy(ildim, obldim, ildim.Length);
  • 使用数组转型有性能损失,对数组元素赋值时,CLR必须在运行时检查数组包含元素的类型是否与新元素类型相符.
  • System.Buffer.BlockCopy() 方法比 Array.Copy() 方法快,但前者只支持基元类型,不提供像 Array 的 Copy 方法那样的转型能力.
  • Array.ConstrainedCopy 方法要么完成复制,要么抛出异常,总之不会破坏目标数组中的数据.

16.3 所有数组都隐式派生自 System.Array

16.4 所有数组都隐式实现 IEnumerable, ICollection 和 IList

  • System.Array 实现了 IEnumerable,ICollectionIList 三个接口,但未实现其对应的泛型接口.
  • CLR 创建一维 0 基数组类型时,CLR 自动使数组类型实现 IEnumerable<T>,ICollection<T>IList<T>(T是数组元素的类型) 接口.同时,还为数组类型的所有基类型实现这三个泛型接口,只要它们是引用类型(数组元素为值类型的,不为数组的基类型实现接口).

16.5 数组的传递和返回

  • 数组作为实参传给方法时,实际传递的是对该数组的引用.因此,被调用的方法能修改数组中的元素.
  • 方法返回数组对象时,如果元素数量为 0 ,强烈建议返回一个空数组,而不是 null ,因为调用方法时可以省去 null 检查.

16.6 创建下限非零的数组

16.7 数组的内部工作原理

  • 访问一维 0 基数组的元素比访问非 0 基一维或多维数组的元素稍快.因为:
    1. 有一些特殊 IL 指令处理一维 0 基数组,导致 JIT 编译器生成优化代码;
    2. For 循环时,JIT 编译器会将对 Length 属性的调用结果缓存起来,每次迭代检查的都是这个临时变量.(不要自作聪明自己缓存 Length 结果)
  • 如要提升性能,可以用交错数组代替矩形数组.
  • 矩形数组的访问方式 a[x,y] ,交错数组的访问方式 a[x][y]

16.8 不安全的数组访问和固定大小的数组

    static class Program
    {
        static void Main(string[] args)
        {
            StackallocDemo();
            InlineArrayDemo();
        }

        private static void StackallocDemo()
        {
            unsafe
            {
                const int width = 20;
                char* pc = stackalloc char[width]; //在栈上分配数组

                string s = "Jeffrey Richter"; //15个字符

                for (int index = 0; index < width; index++)
                {
                    pc[width - index - 1] = (index < s.Length) ? s[index] : '.';
                }

                //下面这行代码显示".....rethciR yerffeJ"
                Console.WriteLine(new String(pc, 0, width));
            }
        }

        private static void InlineArrayDemo()
        {
            unsafe
            {
                CharArray ca;   //在栈上分配数组
                int widthInBytes = sizeof(CharArray);
                int width = widthInBytes / 2; //Char类型占2个字节

                string s = "Jeffrey Richter"; //15个字符

                for (int index = 0; index < width; index++)
                {
                    ca.Characters[width - index - 1] = (index < s.Length) ? s[index] : '.';
                }

                //下面这行代码显示".....rethciR yerffeJ"
                Console.WriteLine(new String(ca.Characters, 0, width));
            }
        }
    }

    internal unsafe struct CharArray
    {
        //这个数组内联(嵌入)到结构中
        public fixed char Characters[20];
    }

在结构中嵌入数组,需满足:

  • 类型必须是结构(值类型);不能在类(引用类型)中嵌入数组.
  • 字段或其定义结构必须用 unsafe 关键字标记.
  • 数组字段必须用 fixed 关键字标记
  • 数组必须是一维 0 基数组.
  • 数组的元素类型必须是以下类型之一:Boolean,Char,SByte,Byte,Int16,Int32,UInt16,UInt32,Int64,UInt64,Single,Double

返回目录

文章评论

程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
总结2014中国互联网十大段子
总结2014中国互联网十大段子
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员都该阅读的书
程序员都该阅读的书
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
代码女神横空出世
代码女神横空出世
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
中美印日四国程序员比较
中美印日四国程序员比较
每天工作4小时的程序员
每天工作4小时的程序员
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序员必看的十大电影
程序员必看的十大电影
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
如何成为一名黑客
如何成为一名黑客
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
一个程序员的时间管理
一个程序员的时间管理
漫画:程序员的工作
漫画:程序员的工作
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
我是如何打败拖延症的
我是如何打败拖延症的
程序员的鄙视链
程序员的鄙视链
 程序员的样子
程序员的样子
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
为什么程序员都是夜猫子
为什么程序员都是夜猫子
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
那些争议最大的编程观点
那些争议最大的编程观点
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
我的丈夫是个程序员
我的丈夫是个程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
10个调试和排错的小建议
10个调试和排错的小建议
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员应该关注的一些事儿
程序员应该关注的一些事儿
程序员和编码员之间的区别
程序员和编码员之间的区别
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
编程语言是女人
编程语言是女人
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有