1. 数组隐式继承 System.Array,所以数组是引用类型。变量包含的是对数组的引用,而不是包含数据本身的元素。

2. 数组协变性。将数组从一种类型转换为另一种类型。

string[] sa = new string[100];
object[] oa = sa;
oa[5] = "Jeff"; // 性能损失:CLR检查oa的元素类型是不是String;检查通过
oa[3] = 5; // 性能损失:CLR检查oa的元素类型是不是Int32;发现有错,抛异常

System.Buffer的BlockCopy方法,只支持基元类型,不具有转型能力。

System.Array的ConstrainedCopy方法,要么完美复制,要么抛出异常,不会破坏目标数组中的数据,不执行装箱、拆箱和向下类型转换。

3. 所有数组都隐式实现 IEnumerable,ICollection,IList

4. 创建下限非0的数组

int[] lowerBounds = { 2015, 1 };
int[] lengths = { 5, 4 };
decimal[,] quarterlyRevenue = (decimal[,])Array.CreateInstance(typeof(decimal), lengths, lowerBounds);
Console.WriteLine("{0,4} {1,9} {2,9} {3,9} {4,9}", "year", "Q1", "Q2", "Q3", "Q4");
int fristYear = quarterlyRevenue.GetLowerBound(0); // 2015
int lastYear = quarterlyRevenue.GetUpperBound(0); // 2019
int fristQuarter = quarterlyRevenue.GetLowerBound(1); // 1
int lastQuarter = quarterlyRevenue.GetUpperBound(1); // 4
for (int year = fristYear; year <= lastYear; year++)
{
Console.Write(year + " ");
for (int quarter = fristQuarter; quarter < lastQuarter; quarter++)
{
Console.Write("{0,9:C} ", quarterlyRevenue[year, quarter]);
}
Console.WriteLine();
}

5. 数组只有两种,下限为0的一维数组(System.String[])和下限未知的多维数组(System.String[,])。1维1基数组(System.String[*])C#不允许使用。访问一维0基数组比访问非0基多维数组要快,因为在for循环中JIT编译器会生成代码来检查是否 0 >= GetLowerBound(0) && (length-1) <= GetUpperBound(0),一维0基数组只会在for循环前检查1次,非0基多维数组则每次都会检查。

private const int c_numElements = 10000;
public static void Main()
{
int[,] a2Dim = new int[c_numElements, c_numElements];
int[][] aJagged = new int[c_numElements][];
for (int x = 0; x < c_numElements; x++)
{
aJagged[x] = new int[c_numElements];
} Safe2DimArrayAccess(a2Dim); SafeJaggedArrayAccess(aJagged); Unsafe2DimArrayAccess(a2Dim);
}
private static int Safe2DimArrayAccess(int[,] a)
{
int sum = 0;
for (int x = 0; x < c_numElements; x++)
{
for (int y = 0; y < c_numElements; y++)
{
sum += a[x, y];
}
}
return sum;
}
private static int SafeJaggedArrayAccess(int[][] a)
{
int sum = 0;
for (int x = 0; x < c_numElements; x++)
{
for (int y = 0; y < c_numElements; y++)
{
sum += a[x][y];
}
}
return sum;
}
private static unsafe int Unsafe2DimArrayAccess(int[,] a)
{
int sum = 0;
fixed (Int32* pi = a)
{
for (int x = 0; x < c_numElements; x++)
{
int baseOfDim = x * c_numElements;
for (int y = 0; y < c_numElements; y++)
{
sum += pi[baseOfDim + y];
}
}
}
return sum;
}

6. 栈上分配数组

public static void Main()
{
StackallocDemo();
InlineArrayDemo();
}
private static void StackallocDemo()
{
unsafe
{
const int width = 20;
Char* pc = stackalloc char[width]; // 在栈上分配数组
string s = "Jeffrey Richter";
for (int index = 0; index < width; index++)
{
pc[width - index - 1] = (index < s.Length) ? s[index] : '.';
}
Console.WriteLine(new string(pc, 0, width));
}
} private static void InlineArrayDemo()
{
unsafe
{
CharArray ca;
Int32 widthInByBytes = sizeof(CharArray);
Int32 width = widthInByBytes / 2; string s = "Jeffrey Richter";
for (int index = 0; index < width; index++)
{
ca.Characters[width - index - 1] = (index < s.Length) ? s[index] : '.';
}
Console.WriteLine(new string(ca.Characters, 0 ,width));
}
} internal unsafe struct CharArray
{
public fixed Char Characters[20];
}

CLR via C# 笔记 -- 数组(16)的更多相关文章

  1. <NET CLR via c# 第4版>笔记 第16章 数组

    //创建一个一维数组 int[] myIntegers; //声明一个数组引用 myIntegers = new int[100]; //创建含有100个int的数组 //创建一个二维数组 doubl ...

  2. Flutter学习笔记(16)--Scaffold脚手架、AppBar组件、BottomNavigationBar组件

    如需转载,请注明出处:Flutter学习笔记(15)--MaterialApp应用组件及routes路由详解 今天的内容是Scaffold脚手架.AppBar组件.BottomNavigationBa ...

  3. javaSE学习笔记(16)---网络编程

    javaSE学习笔记(16)---网络编程 基本概念 如今,计算机已经成为人们学习.工作.生活必不可少的工具.我们利用计算机可以和亲朋好友网上聊天,也可以玩网游.发邮件等等,这些功能实现都离不开计算机 ...

  4. java JDK8 学习笔记——第16章 整合数据库

    第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...

  5. RocketMQ学习笔记(16)----RocketMQ搭建双主双从(异步复制)集群

    1. 修改RocketMQ默认启动端口 由于只有两台机器,部署双主双从需要四个节点,所以只能修改rocketmq的默认启动端口,从官网下载rocketmq的source文件,解压后使用idea打开,全 ...

  6. 《C#本质论》读书笔记(16)构建自定义集合

    16.1 更多集合接口 集合类(这里指IEnumerable层次结构)实现的接口层次结构 16.1.1 IList<T>与IDictionary<TKey,TValue> 字典 ...

  7. 读CLR via C#笔记

    1.is 和 as 的区别 public class Employee { } a): object obj = new Employee(); if (obj is Employee) { Empl ...

  8. Java菜鸟学习笔记--数组篇(三):二维数组

    定义 //1.二维数组的定义 //2.二维数组的内存空间 //3.不规则数组 package me.array; public class Array2Demo{ public static void ...

  9. php 学习笔记 数组3

    15.使用数组 1).并集(union)  array_merge(array1,array2,array3..) 函数把两个或多个数组合并为一个数组,后面覆盖前面 2). 交集(intersecti ...

  10. java笔记 -- 数组

    概念: 数组是一种数据结构, 用来存储同一类型值的集合. 通过一个整型的下标可以访问数组中的每一个值. 声明: int[] a(推荐,将类型int[](整形数组)和变量名分开了) 或者int a[] ...

随机推荐

  1. 如何拥有自己的专属GPT-本地部署目前最强大模型llama3

    你是不是苦于没法使用ChatGPT?或者访问了ChatGPT却没法使用GPT4?现在一切问题都可以解决了! 4月18日,Meta发布两款开源Llama 3 8B与Llama 3 70B模型,供外部开发 ...

  2. Web Audio API 第6章 高级主题

    高级主题 这一章涵盖了非常重要的主题,但比本书的其他部分稍微复杂一些. 我们会深入对声音添加音效,完全不通过任何音频缓冲来计算合成音效, 模拟不同声音环境的效果,还有关于空 3D 空间音频. 重要理论 ...

  3. [python] 基于PyWaffle库绘制华夫饼图

    华夫饼图Waffle chart是一种独特而直观的图表,用于表示分类数据.它采用网格状排列的等大小方格或矩形,每个方格或矩形分配不同的颜色或阴影来表示不同的类别.这种可视化方法有效地传达了每个类别在整 ...

  4. 羽夏看Linux内核——简述

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  5. ansible(4)--ansible的command和shell模块

    1. command模块 功能:在远程主机执行 shell 命令:为默认模块,可省略 -m 选项: 注意:不支持管道命令 |: command模块的常用参数如下: 参数 说明 chdir DIR 执行 ...

  6. CF933-Div3 大致思路+题解

    \(Rank\) A - Rudolf and the Ticket 纯水题 暴力枚举直接过 $code$ #include<bits/stdc++.h> #define fo(x,y,z ...

  7. NETCore中实现一个轻量无负担的极简任务调度ScheduleTask

    至于任务调度这个基础功能,重要性不言而喻,大多数业务系统都会用到,世面上有很多成熟的三方库比如Quartz,Hangfire,Coravel 这里我们不讨论三方的库如何使用 而是从0开始自己制作一个简 ...

  8. rsync备份服务器部署详情

    rsync  -avz --bwlimit=1024M /data/wanxhe  rsync_backup@10.x.x.38::backup/gpu007/data/ --password-fil ...

  9. 【漏洞复现】用友NC-Cloud PMCloudDriveProjectStateServlet接口存在JNDI注入漏洞

    阅读须知 花果山的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站.服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作.利用此 ...

  10. linux下常用的快捷键和$参数

    1.下面介绍两个在linux下非常有用的$参数 2.!$ 表示引用上一个命令的最后一个参数,例子如下: [root@node5 ~]# echo '!$的作用是引用上一个命令的最后一个参数' > ...