如果需要使用不同类型 的多个对象,可以使用Tuple(元组)类型
同一类型的多个对象 : 数组
指定数组大小之后,如果不赋值数组中的所有元素,就不能重新设置数组的大小。
数组声明之后,就不能修改其阶数
Array是一个抽象类,所以不能使用构造函数来创建数组
可以使用静态方法 CreateInstance() 创建数组, 在事先不知道 元素的类型情况下 分厂游泳,因为类型可以用作type对象传递给 CreateInstance
public static Array CreateInstance( Type elementType, int[] lengths,int[] lowerBounds)
int[] lengths 指定每个维度的大小
int[] lowerBounds 指定每个维度的下限
即使 数组不是基于0,但可以用一般的C# 表示法 将它赋予 一个变量
数组是引用类型
如果数组的元素是值类型,复制数组时会复制所有值
如果数组包含引用类型,则不复制元素,而只复制引用。
array1.Clone();可以拷贝数组
Array.Copy()方法创建浅表副本。
Clone() 会创建一个新数组,而Copy() 方法必须传递阶数相同且有足够元素的已有数组
数组协变只能使用 引用类型 不能使用值类型,数组协变只能使用运行时异常来解决
ArraySegment<T>
数组分割,使用不同的方法处理数组的不同部分,比使用多个数组更有效
数组段不能复制原数组中的元素,但原数组可以通过ArraySegment<T>来访问
如果数组段中的元素改变了,这些变化就会反映到原数组中
var segments = new ArraySegment<int>[2]
{
new ArraySegment<int>(arr1,0,3),
new ArraySegment<int>(arr2,4,3)
};
var sum = SumOfSegment(segments);
foreach语句不会解析为IL 代码中的foreach 语句。编译器会把foreach语句转换成IEnumable接口的方法和属性
foreach (var p in persons)
{
Console.WriteLine(p);
}
会解析为下面代码段。
首先调用GetEnumerator()方法获得一个数组的枚举器
IEnumerator<Person> enumerator = persons.GetEnumerator();
在 while 循环中 只要MoveNext() 返回true 就用Current属性访问数组中的元素
while(enumerator.MoveNext()){
Person p = enumerator.Current;
Conson.WriteLine(p);
}
yield 语句,用于创建枚举器
yield return 语句返回集合的一个元素,并移动到下一个元素上
yield break 可停止迭代
包含yiled语句的方法或者属性也成为迭代块,迭代块必须生命为返回IEnumerator或IEnumerable接口,
或者这些接口的泛型版本。
可以包含多个yield return语句 或 yield break语句,但不能包含return语句
yield 语句会生成一个枚举器,而不仅仅生成一个包含的项的列表。
数组合并了相同类型的对象 , 而 元组 合并了不同类型的对象
8个Tuple类 和一个静态Tuple类,用作元组的工厂
不同的泛型 Tuple 类支持不同数量的元素。
Tuple<T1>包含一个元素,Tuple<T1,T2>包含两个元素,以此类推