目录
C# 可空类型(Nullable)
C# 可空类型(Nullable)
Null 合并运算符( ?? )
C# 数组(Array)
一维数组
声明及初始化赋值数组
多维数组
声明和初始化多维数组
访问和操作多维数组
实例
交错数组
声明和初始化交错数组
访问和操作交错数组
实例
交错数组与二维数组的区别
传递数组给函数
实例
参数数组
params 关键字
实例
Array 类
Array 类的属性
Array 类的方法
实例
C# 可空类型(Nullable)
C# 可空类型(Nullable)
可空类型允许我们在值类型中包含 null 值,这在处理数据库查询结果或需要表示缺失值的情况时非常有用。
声明一个可空类型的语法如下:
< data_type>? <variable_name> = null;
其中 <data_type> 是基础的值类型,例如 int、bool 等,? 符号表示这是一个可空类型,<variable_name> 是变量名,= 后面的 null 表示初始时该可空类型变量的值为 null。
对于 Nullable<T> 类型,编译器会执行一些特殊的处理,使得我们可以将 null 赋值给值类型,而不会出现编译错误。同时,Nullable<T> 类型也提供了一些属性和方法来方便地处理可空类型的值,比如 HasValue 来判断是否有值,Value 来获取值,GetValueOrDefault() 来获取值或默认值等。
使用可空类型可以很好地应对实际应用中遇到的可能存在缺失值的情况,同时也可以简化对数据库等数据源的处理。
下面的实例演示了可空数据类型的用法:
using System;
public class CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
int? num1 = null;
int? num2 = 45;
double? num3 = new double?();
double? num4 = 3.14157;
bool? boolval = new bool?();
// 显示值
Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}",
num1, num2, num3, num4);
Console.WriteLine("一个可空的布尔值: {0}", boolval);
Console.ReadLine();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
显示可空类型的值: , 45, , 3.14157
一个可空的布尔值:
Null 合并运算符( ?? )
空合并运算符 ?? 是 C# 中的一个方便的操作符,用于简化处理可能为 null 的情况。它提供了一种简洁的方式来检查并提供默认值,以避免空引用异常。
表达式 a ?? b 表示,如果 a 不为 null,则结果为 a 的值;如果 a 为 null,则结果为 b 的值。
以下是空合并运算符的一些特点和用法:
- 当 a 不为 null 时,表达式的值为 a 的值。
- 当 a 为 null 时,表达式的值为 b 的值。
- a 和 b 的类型必须相同或兼容,否则会出现编译错误。
- 空合并运算符可以在任何具有可空类型或引用类型的情况下使用。
下面是一个简单的示例,演示了空合并运算符的使用:
using System;
public class CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
int? x = null;
int y = x ?? 5; // 如果 x 不为 null,则 y 的值为 x 的值,否则为 5
string name = null;
string result = name ?? "Guest"; // 如果 name 不为 null,则 result 为 name 的值,否则为 "Guest"
Console.WriteLine("y 的值: {0}", y);
Console.WriteLine("result 的值: {0}", result);
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
y 的值: 5
result 的值: Guest
C# 数组(Array)
数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。
声明数组变量并不是声明 number0、number1、...、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。
所有的数组都是由连续的内存位置组成的。最低的地址对应第一个元素,最高的地址对应最后一个元素。
一维数组
声明及初始化赋值数组
在 C# 中,声明数组需要指定数组的类型和名称,并可以选择指定数组的长度或初始化元素。
以下是几种常见的声明及初始化赋值数组的方式:
1、声明并初始化一个固定长度的数组:
int[] numbers = new int[5]; // 创建一个包含 5 个整数的数组
string[] names = new string[3]; // 创建一个包含 3 个字符串的数组
2、声明并初始化一个具有初始值的数组:
int[] numbers = new int[] { 1, 2, 3, 4, 5 }; // 创建一个包含 1、2、3、4 和 5 的整数数组
string[] names = new string[] { "Alice", "Bob", "Charlie" }; // 创建一个包含三个字符串的数组
3、使用简化的语法进行声明和初始化(仅适用于局部变量):
int[] numbers = { 1, 2, 3, 4, 5 }; // 类型推断,创建一个包含 1、2、3、4 和 5 的整数数组
string[] names = { "Alice", "Bob", "Charlie" }; // 类型推断,创建一个包含三个字符串的数组
在上述示例中,int[] 表示整数数组的类型,string[] 表示字符串数组的类型。使用 new 关键字创建一个新的数组实例,并指定数组的长度或初始化元素。
需要注意的是,数组的索引从 0 开始。可以通过索引来访问和修改数组中的元素,例如 numbers[0] 访问第一个元素,numbers[3] = 10 将第四个元素的值设置为 10。
下面是一个实例:
using System;
class Program
{
static void Main()
{
// 声明并初始化一个整数数组
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
// 声明并初始化一个字符串数组
string[] names = new string[] { "Alice", "Bob", "Charlie" };
// 使用简化的语法进行声明和初始化
int[] otherNumbers = { 6, 7, 8, 9, 10 };
string[] otherNames = { "Dave", "Eve", "Frank" };
// 访问和修改数组中的元素
Console.WriteLine("numbers[0]: " + numbers[0]); // 输出:1
Console.WriteLine("names[1]: " + names[1]); // 输出:Bob
numbers[3] = 12; // 修改数组中的元素
Console.WriteLine("numbers[3] 修改后: " + numbers[3]); // 输出:12
// 遍历数组并输出所有元素
Console.WriteLine("数字数组中的所有元素:");
foreach (int number in numbers)
{
Console.WriteLine(number);
}
Console.ReadLine();
}
}
在上述示例中,我们创建了一个 Program 类,并在 Main 方法中进行了数组的声明、初始化和操作。首先,我们声明并初始化了两个数组 numbers 和 names,然后使用简化的语法声明并初始化了 otherNumbers 和 otherNames 数组。
接下来,我们展示了如何访问和修改数组中的元素。使用索引可以获取特定位置的元素的值,也可以修改元素的值。
最后,我们使用 foreach 循环(也可以使用 for 循环来访问每个数组元素)遍历数组并逐个输出所有元素。
多维数组
多维数组是数组的一种特殊形式,它允许在一个数组中存储多个维度的数据。在 C# 中,我们可以创建二维甚至更高维度的数组来表示表格、矩阵、立方体等数据结构。
声明和初始化多维数组
在 C# 中,可以使用以下语法来声明和初始化二维数组:
// 声明并初始化一个二维整数数组
int [,] matrix = new int [3,4] {
{0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
{4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
{8, 9, 10, 11} /* 初始化索引号为 2 的行 */
};
上述代码中,我们声明了一个名为 matrix 的二维整数数组,它包含 3 行和 4 列。
访问和操作多维数组
可以使用索引来访问多维数组中的元素。对于二维数组,我们使用两个索引来表示行和列:
// 访问和修改二维数组中的元素
matrix[0, 0] = 1; // 设置第一行第一列的元素值为 1
int value = matrix[1, 2]; // 获取第二行第三列的元素值
实例
using System;
class Program
{
static void Main()
{
// 声明并初始化一个二维整数数组
int[,] matrix = new int[3, 4];
// 给数组赋值
matrix[0, 0] = 1;
matrix[0, 1] = 2;
matrix[0, 2] = 3;
matrix[0, 3] = 4;
matrix[1, 0] = 5;
matrix[1, 1] = 6;
matrix[1, 2] = 7;
matrix[1, 3] = 8;
matrix[2, 0] = 9;
matrix[2, 1] = 10;
matrix[2, 2] = 11;
matrix[2, 3] = 12;
// 访问和输出二维数组中的元素
Console.WriteLine("matrix[1, 2]: " + matrix[1, 2]); // 输出:7
// 遍历二维数组并输出所有元素
Console.WriteLine("矩阵阵列中的所有元素:");
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write(matrix[i, j] + " ");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
当上面的代码被编译和执行时,它会产生下列结果:
matrix[1, 2]: 7
矩阵阵列中的所有元素:
1 2 3 4
5 6 7 8
9 10 11 12
交错数组
交错数组(jagged array)是 C# 中的一种特殊数组形式,它允许在一个数组中存储其他数组作为其元素。与普通的多维数组不同,交错数组的各个维度的长度可以不同,因此它可以用来表示不规则的数据结构。
声明和初始化交错数组
在 C# 中,可以使用以下语法来声明和初始化一个交错数组:
// 声明并初始化一个交错数组
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] { 1, 2, 3 };
jaggedArray[1] = new int[] { 4, 5 };
jaggedArray[2] = new int[] { 6, 7, 8, 9 };
在上述示例中,我们声明并初始化了一个名为 jaggedArray 的交错数组。它包含了三个子数组,每个子数组的长度可以不同。
访问和操作交错数组
可以使用索引来访问交错数组中的元素,例如:
// 访问并输出交错数组中的元素
Console.WriteLine(jaggedArray[1][0]); // 输出:4
实例
using System;
class Program
{
static void Main()
{
// 声明并初始化一个交错数组
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] { 1, 2, 3 };
jaggedArray[1] = new int[] { 4, 5 };
jaggedArray[2] = new int[] { 6, 7, 8, 9 };
// 访问并输出交错数组中的元素
Console.WriteLine("jaggedArray[1][0]: " + jaggedArray[1][0]); // 输出:4
// 遍历交错数组并输出所有元素
Console.WriteLine("交错数组中的所有元素:");
for (int i = 0; i < jaggedArray.Length; i++)
{
for (int j = 0; j < jaggedArray[i].Length; j++)
{
Console.Write(jaggedArray[i][j] + " ");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
在上述示例中,我们声明并初始化了一个名为 jaggedArray 的交错数组。然后,我们访问了交错数组中的特定元素,并使用嵌套的循环遍历了整个交错数组,并逐个输出了所有元素。
交错数组与二维数组的区别
-
维度不同:交错数组是由多个一维数组组成的数组,每个子数组的长度可以不同。而二维数组是一个由固定长度的一维数组组成的矩阵,每个一维数组具有相同的长度。
-
内存布局不同:交错数组的各个子数组在内存中是连续存储的,但各个子数组之间可能不连续。而二维数组是在内存中按矩阵布局连续存储的。
-
初始化方式不同:交错数组可以通过逐个初始化子数组来构建,每个子数组的长度可以根据需要动态设置。而二维数组需要在声明时指定每个维度的长度,并且无法在后续修改。
-
访问方式不同:由于内存布局不同,访问交错数组和二维数组的元素的方式也有所不同。对于交错数组,我们首先访问主数组的元素,然后再通过索引访问子数组的元素。而对于二维数组,我们可以直接通过两个索引访问元素,从而获得更直观的访问方式。
传递数组给函数
实例
下面的实例演示了如何传递数组给函数:
using System;
class Program
{
static void Main()
{
int[] arr = { 1, 2, 3, 4, 5 };
// 调用函数并传递数组作为参数
ProcessArray(arr);
Console.ReadLine();
}
// 接收数组作为参数的函数
static void ProcessArray(int[] array)
{
Console.WriteLine("接收的数组:");
foreach (int element in array)
{
Console.Write(element + " ");
}
}
}
在这个示例中,我们定义了一个名为 ProcessArray 的函数,它接收一个 int 类型的数组作为参数。在 Main 函数中,我们创建了一个数组 arr,然后将它作为参数传递给 ProcessArray 函数。
当运行这段代码时,ProcessArray 函数将会接收到数组,并输出数组中的所有元素。
参数数组
params 关键字
在 C# 中,可以使用参数数组(params array)来接受可变数量的参数。参数数组允许在函数调用时传递一个可变长度的参数列表,而不需要显式地创建一个数组。
params 的使用格式为:
public 返回类型 方法名称( params 类型名称[] 数组名称 )
实例
using System;
class Program
{
static void Main()
{
// 调用函数并传递多个参数
PrintNumbers(1, 2, 3, 4, 5);
Console.ReadLine();
}
// 使用参数数组的函数
static void PrintNumbers(params int[] numbers)
{
Console.WriteLine("接收的数组:");
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
}
在上述示例中,我们定义了一个名为 PrintNumbers 的函数,它使用参数数组来接收可变数量的整数参数。在 Main 函数中,我们调用了 PrintNumbers 函数,并传递了多个整数参数。
当你运行这段代码时,PrintNumbers 函数会接收到传递的参数,并逐个输出它们。
需要注意的是,
- 带 params 关键字的参数类型必须是一维数组,不能用于多维数组。
- params 关键字不允许与 ref 或 out 关键字同时使用。因为 ref 和 out 都是用来传递参数的引用,而 params 是用来接收可变数量的参数的,它们的语义不兼容。
- 带 params 关键字的参数必须是方法声明中的最后一个参数,并且在同一个方法声明中只允许出现一个 params 关键字。
- 不能仅使用 params 来区分重载的方法。编译器无法准确地确定调用哪个重载方法,因为对于参数数量不确定的情况,重载方法的选择将变得模糊。
- 没有 params 关键字的方法在重载决策中具有更高的优先级。
Array 类
Array 类的属性
下表列出了 Array 类中一些最常用的属性:
序号 | 属性 & 描述 |
---|---|
1 | IsFixedSize 获取一个值,该值指示数组是否带有固定大小。 |
2 | IsReadOnly 获取一个值,该值指示数组是否只读。 |
3 | Length 获取一个 32 位整数,该值表示所有维度的数组中的元素总数。 |
4 | LongLength 获取一个 64 位整数,该值表示所有维度的数组中的元素总数。 |
5 | Rank 获取数组的秩(维度)。 |
如需了解 Array 类的完整的属性列表,请参阅微软的 C# 文档。
Array 类的方法
下表列出了 Array 类中一些最常用的方法:
序号 | 方法 & 描述 |
---|---|
1 | Clear 根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null。 |
2 | Copy(Array, Array, Int32) 从数组的第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。长度由一个 32 位整数指定。 |
3 | CopyTo(Array, Int32) 从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定。 |
4 | GetLength 获取一个 32 位整数,该值表示指定维度的数组中的元素总数。 |
5 | GetLongLength 获取一个 64 位整数,该值表示指定维度的数组中的元素总数。 |
6 | GetLowerBound 获取数组中指定维度的下界。 |
7 | GetType 获取当前实例的类型。从对象(Object)继承。 |
8 | GetUpperBound 获取数组中指定维度的上界。 |
9 | GetValue(Int32) 获取一维数组中指定位置的值。索引由一个 32 位整数指定。 |
10 | IndexOf(Array, Object) 搜索指定的对象,返回整个一维数组中第一次出现的索引。 |
11 | Reverse(Array) 逆转整个一维数组中元素的顺序。 |
12 | SetValue(Object, Int32) 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定。 |
13 | Sort(Array) 使用数组的每个元素的 IComparable 实现来排序整个一维数组中的元素。 |
14 | ToString 返回一个表示当前对象的字符串。从对象(Object)继承。 |
如需了解 Array 类的完整的方法列表,请参阅微软的 C# 文档。
实例
using System;
namespace ArrayApplication
{
class MyArray
{
static void Main()
{
int[] list = { 34, 72, 13, 44, 25, 30, 10 };
Console.Write("原始数组: ");
foreach (int i in list)
{
Console.Write(i + " ");
}
Console.WriteLine();
// 逆转数组
Array.Reverse(list);
Console.Write("逆转数组: ");
foreach (int i in list)
{
Console.Write(i + " ");
}
Console.WriteLine();
// 排序数组
Array.Sort(list);
Console.Write("排序数组: ");
foreach (int i in list)
{
Console.Write(i + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
原始数组: 34 72 13 44 25 30 10
逆转数组: 10 30 25 44 13 72 34
排序数组: 10 13 25 30 34 44 72