初始化数组元素:
class Program { static void Main(string[] args) { String[] names = new String[] { "Adian", "Grant" }; // 隐式类型的局部变量 var myNames = new String[] { "Adian", "Grant", null }; // 隐式类型的局部变量和隐式类型的数组功能 var myAnotherNames = new[] { "Adian", "Grant", (123).ToString() }; // 隐式类型的局部变量、隐式类型的数组和匿名类型功能 var kids = new[] { new { Name = "Adian" }, new { Name = "Grant" } }; foreach (var kid in kids) { Console.WriteLine(kid.Name); } } }
数组协变性:
将数组从一种类型转换为另一种类型;利用协变性时,应该清楚由此而来的性能损失。
class Program { static void Main(string[] args) { FileStream[,] fs2dim = new FileStream[5, 10]; Object[,] o2dim = fs2dim; Stream[,] s2dim = (Stream[,])o2dim; // 能通过编译,但在运行时会抛出InvalidCastException异常 String[,] st2dim = (String[,])o2dim; Int32[] i1dim = new Int32[5]; Object[] o1dim = new Object[i1dim.Length]; // 不能将值类型的数组转型为其他任何类型,因此使用Array.Copy // 将数组中的每一个元素转换为目标数组中的元素类型,并将其复制过去 Array.Copy(i1dim, o1dim, i1dim.Length); Console.ReadLine(); } }
所有数组都隐式派生自System.Array
声明一个数组变量FileStream[] fsArray; System.Array类型定义的所有实例方法和属性都将由FileStream[]继承,这些方法和属性能通过fsArray变量调用。此外,fsArray还可以作为参数,用以调用System.Array类型公开的用于数组处理的静态方法;
所有的数组都隐式实现IEnumerable, ICollection和IList
创建一个一维0基数组类型时,CLR会自动使数组类型实现IEnumerable<T>, ICollection<T>和IList<T>,同时,如果T是引用类型,还会为数组类型的所有基类型实现这三个接口;如果是值类型,则不会为基类型实现这三个接口。
class Program { static void Main(string[] args) { // 引用类型的数组 // CLR会实现IEnumerable<FileStream>, ICollection<FileStream>和IList<FileStream> // 以及IEnumerable<Stream>, ICollection<Stream>和IList<Stream> // 以及IEnumerable<Object>, ICollection<Object>和IList<Object> FileStream[] fsArray; // 值类型的数组, // CLR只会实现IEnumerable<DateTime>, ICollection<DateTime>和IList<DateTime> DateTime[] dtArray; Console.ReadLine(); } }
数组的传递和返回
数组作为实参传给一个方法时,实际传递的是对该数组的引用。如果不想数组被修改,必须生成数组的一个拷贝,并将拷贝传给方法。需要注意的是Array.Copy执行的是浅拷贝,如果数组元素是引用类型,新数组将引用现有的对象。
最好设计为返回对含有0个元素的一个数组的引用,而不是返回null。
创建下限非零的数组
使用Array.CreateInstance可以创建非零下限的数组,可以查阅其重载的方法。