对数组的回顾个人理解总结

对数组的定义概念可以理解为:数组是允许将多个数据项作为集合来处理的机制,在运行时(CLR)中也是支持一维或者多为的数组(即是数组构成的数组)。我们定义的数组类型都是继承System.Array抽象类中派生,当然,最终,System.Array继承的是System.Object,所有类型的基类,所以这就意味着,数组也是属于引用类型;在托管堆上分配的(值类型&&引用类型)。在应用程序的变量或者字段中,都是包含的是数组的引用,而不是元素的本身;
Test:定义一个数组
Int32 [] Test; //声明一个数组引用
Test = new Int32[100]; //创建包含有100 个Int32的数组
Test是声明的一个变量,指向了包含Int32[]值得一维数组,从第一行的定义可以看出,Test是一个null值,因为只是定义,并未给它分配数组;在第二行代码中,我给它分配了含有100个Int[]32值的数组,初始化都为0,因为是引用类型的缘故,(在此处要搞清楚什么是引用类型和什么是值类型,此处省略),So会在托管堆上分配100个未装箱的Int32所需的内存块,(内存块包含:类型的对象指针,同步索引,额外的成员:overhead开销字段)
为了符合CLS(公共语言规范)的要求;所以所有的数组都必须是0基数组(那就是最小索引为0),0基数组是目前最常用的数组,所以不用担心其性能上的问题,Microsoft花了很大的力气去优化其性能;
除了有一维数组以外:还有二维,三维,交错数组(数组构成的数组)等等.....
二维:
Double[,] Test1 = new Double[10,20]
三维:
String[,,] Test2 = new String [5,3,10]
交错数组:
Ponit [] [] Test3 = new Point[3][];
Test3[0] = new Point[10]; //Test3[0] 引用了一个含有10 个Point实例的数组
Test3[1] = new Point[20];//Test3[1] 引用了一个含有20 个Point实例的数组
Test3[2] = new Point[30];//Test3[2] 引用了一个含有30 个Point实例的数组
在编译的过程中,CLR会验证数组索引的有效性,所以这种情况下,我们不能创建含有100个元素的数组,然后又去访问索引为-5到100的元素,这样会导致程序异常;抛出错误,这种错误都是很低级的错误;这样子也会造成潜在的安全漏洞;JIT编译器会在每次循环之前都去检查一下数组的边界;
初始化数组元素
通常我们会将数组的定义与初始化这么写:

String [] Names = new String [] {“Amy”,”Aron”};
我们定义了一个String类型的数组,在大括号中以逗号分隔的数据像称为 数组初始化器,每个数组项都可以是一个任意复杂程度的表达式;上面的例子中我们只是用了两个string类型表达式;
在数组中也可以接受“隐式类型的局部变量”让编译器自己去推断数组元素的类型,所以下面这段代码,并没有声明其类型:Var names = new [] {“Amy”, “Arom”,null};
在此句代码中,编译器发现了两个String和一个null,由于null是可以隐式转换成任意引用类型的,所以编译器推断这是一个string引用构成的数组;
虽然是可以隐式转化,但并不是任意类型都是可以混合在一起的,例如这么写:
Var names = new []{“Amy”,”Aron”,123};
这个时候编译器会报错:error CS0826:找不到隐式类型数组的最佳类型;不同类型不能强制混合在一起,即使都是共同的基类Object;隐式对数组元素进行装箱是一个高昂的操作;
但是同是,在C#中,我们允许这么写,增加代码的可读性:没有new,没有具体的类型,没[]号
String [] names = {“amy”,”Arom”};
但值得注意的是,这种写法是不允许出现在隐式类型的局部变量去使用的;
例如:Var names = {“Amy”,”Aron”};
编译以上代码,则会返回错误:
Error:无法用数组初始值设定初始化隐式类型的局部变量Error:只能使用数组初始化值设定项表达式为数组类型赋值,请尝试改用new表达式
此处要注意的重点内容:在赋值操作符右侧只给出了一个初始化器,没有new,没有类型,没有[]号但是是不允许在隐式类型的局部变量去使用的
数组转型元素为引用类型的数组,CLR允许将数组元素从一种类型转换成另一种类型;
有一下几点要求:
①引用类型②数组的维数相同,而且必须存在从元素源类型到目标类型的隐式或显示转换
③不允许值类型的元素去转换转型成其他任何类型;但是可以通过Array.Copy创建一个新的数组并填充
例如:
创建一个二维数组:FileStream[,] test1 = new FileStream[5,10]
隐式转换成二维数组Object数组 Object[,] test2 = test1;
注意:二维数组不能转型为一维数组,所以维数也要一致;
所有的数组都隐式派生自System.Array,所有的数组都隐式实现了IEnumerable,ICollection和Ilist;
如果只是复制数组中的某些元素的话,可以选择System.Buffer中的BlockCopy方法,这个效率上会比Array中的Copy会快一些
下面是一些常用属性和方法:
Length属性(表示元素中的总数):
int [] Test = {1,2,3,4} Test的Length的值为 4 Rank属性:(数组的维数) 
string[,] Test= new string[5,4];
Test.Rank的值为2。

Sort方法:(对数组进行排序,属于Array类的静态方法) 
string [] Test=new string[]{"Amy","Ben","Aron","KiMi"};
Array.Sort(Test);
Clear方法 :(将数组重新初始化,元素设置为0,false,null),Clear()使用的领域比较多,基本很多控件,实体类,使用清空操作时都能调用Clear
string [] Test=new string[]{"Amy","Ben","Aron","KiMi"};
Test.Clear();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值