数组
数组是一种特殊类型的数据类型,它可以使用特殊语法顺序存储固定数量的值。
数组声明
int [] intArr;
数组初始化:使用new
关键字同时声明和初始化数组,下面三种方式等价
int[] intArr = new int[5];
int[] intArr = new int[5]{1, 2, 3, 4, 5};
int[] intArr = {1, 2, 3, 4, 5};
延迟初始化:可以先声明后再初始化数组
string[] strArr, strArr;
strArr = new string[5]{ "1st Element","2nd Element", "3rd Element"};
strArr = new string[]{ "1st Element","2nd Element", "3rd Element"};
索引访问数组中元素
intArr[索引位置];
方法名称 | 描述 |
---|---|
GetLength(int维度) | 返回指定维度中的元素数 |
GetLowerBound(int维度) | 返回指定维度的最低索引 |
GetUpperBound(int维度) | 返回指定维度的最高索引 |
GetValue(int index) | 返回指定索引处的值 |
属性 | 描述 |
---|---|
Length | 返回数组中元素的总数 |
// 数组可以先声明后赋值,也可以声明同时赋值,下面的方式是等价的,数组中必须存储同一类型数据,这在数组被定义时就已经确定
// 第一种
int[] intArr = new int[5];
intArr[0] = 1;
intArr[1] = 2;
intArr[2] = 3;
intArr[3] = 4;
intArr[4] = 5;
// 第二种
//int[] intArr = new int[5] { 1, 2, 3, 4, 5 };
// 第三种
//int[] intArr = { 1, 2, 3, 4, 5 };
// 注意这里是维度不是索引
Console.WriteLine("GetLength(int维度):返回指定维度中的元素数,值为:{0}", intArr.GetLength(0));
Console.WriteLine("GetLowerBound(int维度):返回指定维度的最低索引,值为:{0}", intArr.GetLowerBound(0));
Console.WriteLine("GetUpperBound(int维度):返回指定维度的最高索引,值为:{0}", intArr.GetUpperBound(0));
Console.WriteLine("GetValue(int index): 返回指定索引处的值,值为:{0}", intArr.GetValue(2));
Console.WriteLine("属性:Length:返回数组中元素的总数,值为:{0}", intArr.Length);
// 使用索引来访问数组元素
Console.WriteLine("使用索引访问数组元素,索引为2的值为:{0}", intArr[2]);
// 试图访问数组中不存在的索引元素,会发生数组越界
Console.WriteLine("使用索引访问数组元素,索引为10的值为:{0}", intArr[10]);
for (int i = 0; i < intArr.Length; i++)
{
Console.WriteLine(intArr[i]);
}
foreach (var item in intArr)
{
Console.WriteLine(item);
}
多维数组
多维数组是行和列的二维系列。多维数组又称为矩形数组;在本质上,是个一维数组的列表。
// 下面的两种创建方式等价
// 第一种
// int[,] intArray = { { 1, 1 }, { 1, 2 }, { 1, 3 } };
// 第二种
int[,] intArray = new int[3, 4]{ //初始化化一个三行四列的数组
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
// 下面的语句将获取数组中第3行第4个元素
Console.WriteLine("二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问,值为:{0}", intArray[2, 3]);
Console.WriteLine("属性:Length:返回数组中元素的总数,值为:{0}", intArray.Length);
可以使用两个索引访问多维数组的值。第一个索引用于行,第二个索引用于列。两个索引都从零开始。
锯齿状数组
锯齿状数组是数组的数组。Jagged
数组直接存储数组而不是任何其他数据类型值。锯齿状数组用两个方括号 [][]
初始化。
第一个括号指定数组的大小,第二个括号指定将作为值存储的数组的维度。(锯齿状数组总是存储一个数组),二维数组的大小是矩形的。
例如:3×3个元素。而锯齿数组的大小设置是比较灵活的,在锯齿数组中,每一行都可以有不同的大小
int[][] intJaggedArray = new int[2][];
intJaggedArray[0] = new int[3]{1,2,3};
intJaggedArray[1] = new int[2]{4,5};
Console.WriteLine(intJaggedArray[0][0]); // 1
Console.WriteLine(intJaggedArray[0][2]); // 3
Console.WriteLine(intJaggedArray[1][1]); // 5
Array
.NET提供了一个抽象类 Array
,作为所有数组的基类。它提供了用于创建,操作,搜索和排序数组的静态方法。**
属性 | 描述 |
---|---|
IsFixedSize | 获取一个值,该值指示数组是否带有固定大小 |
IsReadOnly | 获取一个值,该值指示数组是否只读 |
Length | 获取一个 32 位整数,该值表示所有维度的数组中的元素总数 |
LongLength | 获取一个 64 位整数,该值表示所有维度的数组中的元素总数 |
Rank | 获取数组的秩(维度) |
方法 | 描述 |
---|---|
Clear | 根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null |
Copy(Array,Array,Int32) | 从数组的第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。长度由一个 32 位整数指定 |
CopyTo(Array,Int32) | 从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定 |
GetLength | 获取一个 32 位整数,该值表示指定维度的数组中的元素总数 |
GetLongLength | 获取一个 64 位整数,该值表示指定维度的数组中的元素总数 |
GetLowerBound | 获取数组中指定维度的下界 |
GetType | 获取当前实例的类型。从对象(Object)继承 |
GetUpperBound | 获取数组中指定维度的上界 |
GetValue(Int32) | 获取一维数组中指定位置的值。索引由一个 32 位整数指定 |
IndexOf(Array,Object) | 搜索指定的对象,返回整个一维数组中第一次出现的索引 |
Reverse(Array) | 逆转整个一维数组中元素的顺序 |
SetValue(Object, Int32) | 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定 |
Sort(Array) | 使用数组的每个元素的 IComparable 实现来排序整个一维数组中的元素 |
ToString | 返回一个表示当前对象的字符串。从对象(Object)继承 |
Array arr = Array.CreateInstance(Type.GetType("System.Int32"), 3);
arr.SetValue(1, 0);
arr.SetValue(3, 1);
Console.WriteLine("IsFixedSize:取一个值,该值指示数组是否带有固定大小,值为:{0}", arr.IsFixedSize);
Console.WriteLine("IsReadOnly:取一个值,该值指示数组是否只读,值为:{0}", arr.IsReadOnly);
Console.WriteLine("Length:获取一个 32 位整数,该值表示所有维度的数组中的元素总数,值为:{0}", arr.Length);
Console.WriteLine("LongLength:获取一个 64 位整数,该值表示所有维度的数组中的元素总数,值为:{0}", arr.LongLength);
Console.WriteLine("Rank:获取数组的秩(维度),值为:{0}", arr.Rank);
foreach (var item in arr)
{
Console.WriteLine(item);
}
集合
C#包括在特定系列中包含许多值或对象的专用类,称为集合。C#中有两种类型的集合:非泛型集合
和泛型集合
。每个集合类都实现 IEnumerable
接口,因此可以使用 foreach
循环访问集合中的值。
非泛型集合
System.Collections
中命名空间包括以下非泛型集合:
类型 | 用法 |
---|---|
ArrayList | ArrayList存储任何类型的对象,如数组。但是,当数组自动增长时,无需像数组那样指定ArrayList的大小 |
SortedList | SortedList存储键和值对。它默认按键的升序自动排列元素。C#包括泛型和非泛型SortedList集合 |
Stack | Stack以LIFO样式存储值(后进先出)。它提供了一个Push()方法来添加一个值,Pop()和Peek()方法来检索值。C#包括通用和非通用堆栈 |
Queue | 队列以FIFO样式(先进先出)存储值。它保持添加值的顺序。它提供了一个Enqueue()方法来添加值,还提供了一个Dequeue()方法来从集合中检索值。C#包括通用和非通用队列 |
Hashtable | Hashtable存储键和值对。它通过比较键的哈希值来检索值 |
BitArray | BitArray管理一个紧凑的位值数组,表示为布尔值,其中true表示该位为on(1),false表示该位为off(0) |
ArrayList
可以包含任何数据类型的元素。类似于数组,但是在添加元素时不需要指定ArrayList
的大小会自动增长。
要点:
- 可以存储任何数据类型的项(元素)
- 添加元素时会自动调整大小
- 可以包含多个
null
- 可以使用
foreach
或for
循环或索引器访问
**
属性 | 描述 |
---|---|
Capacity | 获取或设置ArrayList可以包含的元素数 |
Count | 获取ArrayList中实际包含的元素数 |
IsFixedSize | 获取一个值,该值指示ArrayList是否具有固定大小 |
IsReadOnly | 获取一个值,该值指示ArrayList是否为只读 |
Item | 获取或设置指定索引处的元素 |
方法 | 描述 |
---|---|
Add()/AddRange() | Add()方法在ArrayList的末尾添加单个元素。 AddRange()方法将指定集合中的所有元素添加到ArrayList中 |
Insert()/InsertRange() | Insert()方法在ArrayList中的指定索引处插入单个元素。 InsertRange()方法从ArrayList中的指定索引开始插入指定collection的所有元素 |
Remove()/RemoveRange() | Remove()方法从ArrayList中删除指定的元素。 RemoveRange()方法从ArrayList中删除一系列元素 |
RemoveAt() | 从ArrayList中删除指定索引处的元素 |
Sort() | 对ArrayList的整个元素进行排序 |
Reverse() | 反转整个ArrayList中元素的顺序 |
Contains | 检查ArrayList中是否存在指定的元素。如果存在则返回true,否则返回false |
Clear | 删除ArrayList中的所有元素 |
CopyTo | 将所有元素或元素范围复制到compitible Array |
GetRange | 从ArrayList返回指定索引中指定数量的元素 |
IndexOf | 搜索指定的元素并返回零基索引(如果找到)。如果找不到元素,则返回-1 |
ToArray | 从ArrayList返回compitible数组 |
ArrayList arrayList = new ArrayList();
arrayList.Add("wang");
arrayList.Add(1);
// ArrayList允许插入null
arrayList.Add(null);
foreach (var item in arrayList)
{
Console.WriteLine(item);
}
SortedList
SortedList
集合默认按键的升序存储键值对。SortedList
类实现IDictionary
和ICollection
接口,因此可以通过键和索引访问元素。
C#包括两种类型的SortedList
,泛型SortedList
和非泛型SortedList
要点:
- C#具有泛型和非泛型 SortedList
SortedList
按键的升序存储键值对。键必须是唯一的,不能为null
,而值可以为null
或重复项- 非泛型
SortedList
存储任何数据类型的键和值。因此,需要将值转换为适当的数据类型 - 键值对可以强制转换为
DictionaryEntry
- 使用索引器访问单个值。
SortedList
索引器接受键并返回与之关联的值
**
属性 | 描述 |
---|---|
Capacity | 获取或设置SortedList实例可以存储的元素数 |
Count | 获取SortedList中实际包含的元素数 |
IsFixedSize | 获取SortedList中实际包含的元素数 |
IsReadOnly | 获取一个值,该值指示SortedList是否为只读 |
Item | 获取或设置SortedList中指定键的元素 |
Keys | 获取SortedList的键列表 |
Values | 获取SortedList中的值列表 |
方法 | 描述 |
---|---|
Add(object key, object value) | 将键值对添加到SortedList中 |
Remove(object key) | 删除具有指定键的元素 |
RemoveAt(int index) | 删除指定索引处的元素 |
Contains(object key) | 检查SortedList中是否存在指定的键 |
Clear() | 从SortedList中删除所有元素 |
GetByIndex(int index) | 返回存储在内部数组中的索引值 |
GetKey(int index) | 检返回存储在内部数组中指定索引处的键 |
IndexOfKey(object key) | 返回存储在内部数组中的指定键的索引 |
IndexOfValue(object value) | 返回存储在内部数组中的指定值的索引 |
SortedList sortedList = new SortedList();
sortedList.Add(2, "wang");
sortedList.Add(5, "li");
sortedList.Add(3, 5);
//SortedList键可以是任何数据类型,但不能在同一SortedList中添加不同数据类型的键。
sortedList.Add("wang", 32);
for (int i = 0; i < sortedList.Count; i++)
{
Console.WriteLine("key:{0},value:{1}", sortedList.GetKey(i), sortedList.GetByIndex(i));
}
foreach (DictionaryEntry item in sortedList)
{
Console.WriteLine("key:{0},value:{1}", item.Key, item.Value);
}
Stack
C#包含一种特殊类型的集合,它以 LIFO
样式存储元素(后进先出)。
C#包括通用和非通用堆栈,非泛型堆栈。Stack
允许空值以及重复值。它提供了一个 Push()
方法来添加一个值, Pop()
或 Peek()
方法来检索值。
要点:
Stack
将值存储在LIFO(后进先出)
样式中。最后添加的元素将是首先出现的元素- 使用
Push()
方法将元素添加到Stack
中 Pop()
方法返回并从堆栈顶部删除元素。在空Stack
上调用Pop()
方法将引发异常Peek()
方法总是返回Stack
中最顶层的元素
**
属性 | 方法 |
---|---|
Count | 返回Stack中元素的总数 |
方法 | 描述 |
---|---|
Push | 在堆栈顶部插入一个项目 |
Peek | 返回堆栈中的顶部项 |
Pop | 从堆栈顶部删除并返回项目 |
Contains | 检查堆栈中是否存在项目 |
Clear | 从堆栈中删除所有项目 |
Stack stack = new Stack();
stack.Push("1");
stack.Push(1);
stack.Push(false);
foreach (var item in stack)
{
Console.WriteLine(item);
}
Queue
C#包含System.Collection
命名空间中的Queue
集合类。队列以FIFO
样式(先进先出)存储元素。
与Stack
集合完全相反。它按照添加顺序包含元素。队列集合允许多个空值和重复值。使用Enqueue()
方法添加值,使用Dequeue()
方法从队列中检索值。
要点:
- 队列将值存储在
FIFO(先进先出)
样式中。首先添加的元素将首先出现 - 使用
Enqueue()
方法将元素添加到Queue中 Dequeue()
方法返回并从队列的开头删除元素。在空队列上调用Dequeue()
方法将引发异常Peek()
方法总是返回最顶层的元素
属性 | 描述 |
---|---|
Count | 返回Stack中元素的总数 |
方法 | 描述 |
---|---|
Enqueue | 将项添加到队列中 |
Dequeue | 从队列的开头删除并返回一个项目 |
Peek | 返回队列中的第一个项目 |
Contains | 检查项目是否在队列中 |
Clear | 从队列中删除所有项目 |
TrimToSize | 将队列的容量设置为队列中的实际项目数 |
Queue queue = new Queue();
queue.Enqueue("1");
queue.Enqueue(1);
queue.Enqueue(false);
foreach (var item in queue)
{
Console.WriteLine(item);
}
Hashtable
C#包含System.Collections
命名空间中的Hashtable
集合,类似于通用字典集合。Hashtable
集合存储键值对。通过计算每个密钥的哈希码来优化查找,并在内部将其存储在不同的存储桶中,然后在访问值时匹配指定密钥的哈希码。
要点:
- 存储
Key
必须唯一的任何数据类型的键值对 - 键不能为
null
,而值可以为null
- 通过比较键的哈希码来检索项目。因此它的性能比
Dictionary
集合慢 - 使用默认的哈希码提供程序,即
object.GetHash()
。还可以使用自定义哈希码提供程序 - 将
DictionaryEntry
与foreach
语句一起使用以迭代Hashtable
**
属性 | 描述 |
---|---|
Count | 获取Hashtable中键/值对的总数 |
IsReadOnly | 获取布尔值,指示Hashtable是否为只读 |
Item | 获取或设置与指定键关联的值 |
Keys | 获取Hashtable中的键的ICollection |
Values | 获取Hashtable中值的ICollection |
方法 | 描述 |
---|---|
Add | 将具有键和值的项添加到哈希表中 |
Remove | 从散列表中删除具有指定键的项 |
Clear | 从哈希表中删除所有项目 |
Contains | 检查哈希表是否包含特定密钥 |
ContainsKey | 检查哈希表是否包含特定密钥 |
ContainsValue | 检查哈希表是否包含特定值 |
GetHash | 返回指定键的哈希码 |
Hashtable hashtable = new Hashtable();
hashtable.Add(1, "wang");
hashtable.Add(3, false);
hashtable.Add(2, "li");
foreach (DictionaryEntry item in hashtable)
{
Console.WriteLine("key:{0}, value:{1}", item.Key, item.Value);
}
BitArray
BitArray
类管理一个紧凑型的位值数组,它使用布尔值来表示,其中true
表示位是开启的(1),false 表示位是关闭的(0)。当需要存储位,但是事先不知道位数时,则使用点阵列。可以使用整型索引从点阵列集合中访问各项,索引从零开始。
属性 | 描述 |
---|---|
Count | 获取 BitArray 中包含的元素个数。 |
IsReadOnly | 获取一个值,表示 BitArray 是否只读。 |
Item | 获取或设置 BitArray 中指定位置的位的值。 |
Length | 获取或设置 BitArray 中的元素个数。 |
方法 | 描述 |
---|---|
public BitArray And( BitArray value ); | 对当前的 BitArray 中的元素和指定的 BitArray 中的相对应的元素执行按位与操作。 |
public bool Get( int index ); | 获取 BitArray 中指定位置的位的值。 |
public BitArray Not(); | 把当前的 BitArray 中的位值反转,以便设置为 true 的元素变为 false,设置为 false 的元素变为 true。 |
public BitArray Or( BitArray value ); | 对当前的 BitArray 中的元素和指定的 BitArray 中的相对应的元素执行按位或操作。 |
public void Set( int index, bool value ); | 把 BitArray 中指定位置的位设置为指定的值。 |
public void SetAll( bool value ); | 把 BitArray 中的所有位设置为指定的值。 |
public BitArray Xor( BitArray value ); | 对当前的 BitArray 中的元素和指定的 BitArray 中的相对应的元素执行按位异或操作。 |
泛型集合
同传统的集合相比,泛型集合是一种强类型的集合,它解决了类型安全问题,同时避免了集合中每次的装箱与拆箱的操作,提升了性能。
List
List<T>
在C#应用程序中是一种快捷、易于使用的泛型集合类型,使用泛型编程为编写面向对象程序增加了极大的效率和灵活性,不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换。
名称 | 描述 |
---|---|
Add | 将对象添加到 List的结尾处 |
AddRange | 将指定集合的元素添加到 List的末尾 |
AsReadOnly | 返回当前集合的只读 IList包装 |
BinarySearch(T) | 使用默认的比较器在整个已排序的 List中搜索元素,并返回该元素从零开始的索引 |
BinarySearch(T, IComparer) | 使用指定的比较器在整个已排序的 List中搜索元素,并返回该元素从零开始的索引 |
BinarySearch(Int32, Int32, T, IComparer) | 使用指定的比较器在已排序 List的某个元素范围中搜索元素,并返回该元素从零开始的索引 |
Clear | 从 List中移除所有元素 |
Contains | 确定某元素是否在 List中 |
ConvertAll | 将当前 List<T中的元素转换为另一种类型,并返回包含转换后的元素的列表 |
CopyTo(T[]) | 将整个 List<T复制到兼容的一维数组中,从目标数组的开头开始放置 |
Exists | 确定 List<T是否包含与指定谓词所定义的条件相匹配的元素 |
Find | 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List中的第一个匹配 元素 |
FindIndex(Predicate) | 搜索与指定谓词所定义的条件相匹配的元素,并返回整个List 中第一个匹配元素的从零开始的索引 |
ForEach | 对 List的每个元素执行指定操作。 GetEnumerator 返回循环访问 List的枚举器 |
IndexOf(T) | 搜索指定的对象,并返回整个 List中第一个匹配项的从零开始的索引 |
Insert | 将元素插入 List的指定索引处 |
InsertRange | 将集合中的某个元素插入 List的指定索引处 |
LastIndexOf(T) | 搜索指定的对象,并返回整个 List中最后一个匹配项的从零开始的索引 |
Remove | 从 List中移除特定对象的第一个匹配项 |
Reverse() | 将整个 List中元素的顺序反转 |
Sort() | 使用默认比较器对整个 List中的元素进行排序 |
List<intintList = new List<int>();
intList.Add(3);
intList.Add(54);
intList.Add(14);
foreach (var item in intList)
{
Console.WriteLine(item);
}
Stack
以后进先出的方式维护数据的集合,包含pop()
和push()
,从栈内压入或移除数据。
Quenue
以先进先出的方式访问数据,使用Enqueue()
和Dequeue()
添加数据和移除数据。
SortedSet
这个类中的数据是排序的,在插入和移除数据之后仍然能自动排序,需要向其构造函数中传递一个实现了IComparer<T>
,该接口定义了Compare
方法。
ObservableCollection
表示能在添加、移除或者刷新整个列表时提供通知的动态数据集合, ReadOnlyObservableCollection<T>
的操作与之类似,不过是只读的。 ObservableCollection<T>
实现了一个名为CollectionChanged
事件,该事件在插入新的数据或者移除数据时触发。
Dictionary
提供快速的基于键值的元素查找。结构是:Dictionary <[key],[value]>
,当有很多元素的时候可以用它。在使用前,必须声明它的键类型和值类型。
数组/ArrayList/List三者的区别
- 数组:针对特定类型固定长度,值不可为
null
,在声明数组的时候必须指定数组的长度,可有多个维度 - Array:数组的另一种创建方式抽象类,作为所有数组的基类,针对任意类型固定长度,值可以为
null
,输出会被替换为0 - ArrayList:针对任意类型、任意长度的,值可以为
null
,存储或检索值类型时通常发生装箱和拆箱操作,带来很大的性能耗损 List:强类型的集合,固定类型、任意长度,值不可为
null
,是类型安全的索引器(Indexer)
Indexer
是一种特殊类型的属性,允许以与其内部集合的数组相同的方式访问类或结构。除了使用带有方括号和参数的此关键字定义的属性外,它与属性相同。索引器与属性相同,除了它使用带有方括号的此关键字定义,该参数具有参数
- 可以通过具有不同类型的参数来覆盖索引器
- 不支持使用索引器的
Ref
和out
参数 - 索引器可以作为接口成员包含在内
public <return typethis[<parameter typeindex]
{
Get{
// return the value from the specified index
}
Set{
// set values at the specified index
}
}
public class Indexer
{
private int[] indexs = new int[10];
public int this[int index]
{
get { return indexs[index]; }
set
{
indexs[index] = value;
}
}
}
/*
Indexer是一种特殊类型的属性,允许以与其内部集合的数组相同的方式访问类或结构。
除了使用带有方括号和参数的此关键字定义的属性外,它与属性相同。
*/
Console.WriteLine("********************索引器*********************");
Indexer indexer = new Indexer();
indexer[0] = 1;
indexer[1] = 2;
Console.WriteLine(indexer[1]);