一.介绍
C#在2000年6月发布,使用了.NET框架作为运行环境,源于C语言系列,继承了C和C++强大功能的同时去掉了一些它们的复杂特性(例如,没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言[1]。是由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言。
二.变量基础概念
在C#中,变量是存储数据的基本单元,需声明类型和名称后才能使用。变量包含以下核心要素:
- 数据类型:决定变量存储的数据种类(如整数、字符串等)。
- 名称:需遵循标识符命名规则(字母、数字、下划线,且不以数字开头)。
- 值:变量存储的具体数据,可通过赋值操作修改。
变量声明与初始化
声明变量时需指定类型和名称,可选择直接赋值或稍后赋值:
int age; // 声明未初始化
string name = "Alice"; // 声明并初始化
double salary = 5000.50;
数据类型分类
C#变量主要分为两大类:
- 值类型:直接存储数据(如基本类型、结构体)。
int num = 42; bool isActive = true; struct Point { public int X, Y; } - 引用类型:存储数据的内存地址(如类、数组)。
string text = "C#"; int[] numbers = { 1, 2, 3 }; class Person { public string Name; }
变量作用域
变量的可访问范围由其声明位置决定:
- 局部变量:在方法或代码块内声明,仅限块内使用。
void Method() { int localVar = 5; // 仅在此方法内有效 } - 成员变量:在类中声明,作用域为整个类实例。
常量与只读变量
- const:编译时常量,需在声明时赋值且不可修改。
const double PI = 3.14159; - readonly:运行时常量,可在声明或构造函数中赋值。
readonly DateTime CreatedAt = DateTime.Now;
三.运算符
算术运算符
+:加法(数字相加或字符串连接)-:减法或取负*:乘法/:除法(浮点结果)%:取模(求余数)**或^:幂运算(如2**3表示2的3次方)
比较运算符
==:等于!=:不等于>/<:大于/小于>=/<=:大于等于/小于等于
逻辑运算符
&&或and:逻辑与||或or:逻辑或!或not:逻辑非
位运算符
&:按位与|:按位或^:按位异或~:按位取反<</>>:左移/右移- 注:位运算通过直接操作二进制位,能够显著提升某些计算场景的效率,尤其在算法竞赛和系统编程中应用广泛。
赋值运算符
=:基本赋值+=/-=:复合赋值(如x += 1等价于x = x + 1)
三元运算符
语法:条件 ? 表达式1 : 表达式2
运算符优先级
- 括号
()优先级最高 - 单目运算符(如
!、~) - 算术运算符(先乘除后加减)
- 比较运算符
- 逻辑运算符(非→与→或)
四.类型转换
类型转换的基本概念
类型转换是将一个数据类型转换为另一个数据类型的过程。C#中类型转换分为隐式转换和显式转换两种方式。
隐式类型转换
隐式转换由编译器自动完成,通常发生在较小范围类型向较大范围类型转换时,不会丢失数据。
int numInt = 100;
long numLong = numInt; // 自动从 int 转换为 long
float numFloat = numLong; // 自动从 long 转换为 float
显式类型转换(强制转换)
显式转换需要手动指定目标类型,可能引发数据丢失或溢出异常。
double numDouble = 123.45;
int numInt = (int)numDouble; // 强制转换为 int,小数部分被截断
Console.WriteLine(numInt); // 输出 123
Convert 类
Convert 类提供了一系列静态方法用于类型转换,支持更灵活的类型处理。
string strNumber = "456";
int convertedInt = Convert.ToInt32(strNumber); // 字符串转 int
bool convertedBool = Convert.ToBoolean("true"); // 字符串转 bool
Parse 和 TryParse 方法
Parse 方法将字符串转换为目标类型,失败时抛出异常;TryParse 方法安全转换,返回布尔值表示是否成功。
string strValue = "789";
int parsedInt = int.Parse(strValue); // 字符串转 int,失败时抛出异常
string invalidStr = "abc";
bool success = int.TryParse(invalidStr, out int result); // 安全转换,success 为 false
五.选择结构
选择结构的基本概念
选择结构用于根据不同条件执行不同的代码块,常见的实现方式包括 if、else if、else 和 switch 语句。以下是 C# 中的具体示例。
if 语句
根据条件判断是否执行代码块:
int num = 10;
if (num > 0)
{
Console.WriteLine("正数");
}
if-else 语句
条件为真时执行第一个代码块,否则执行第二个代码块:
int num = -5;
if (num >= 0)
{
Console.WriteLine("非负数");
}
else
{
Console.WriteLine("负数");
}
switch 语句
适用于多分支选择,匹配固定值:
char grade = 'B';
switch (grade)
{
case 'A':
Console.WriteLine("优秀");
break;
case 'B':
Console.WriteLine("良好");
break;
case 'C':
Console.WriteLine("及格");
break;
default:
Console.WriteLine("无效等级");
break;
}
三元运算符
简化简单的条件判断:
int a = 5, b = 10;
string result = (a > b) ? "a 更大" : "b 更大";
Console.WriteLine(result);
注意事项
switch语句支持case和default分支,需以break或return结束。- 三元运算符仅适用于简单逻辑,复杂条件建议使用
if-else。 - 在需要进行多次嵌套if语句时,会使代码可读性变差,所以可以用
return来处理。
六.循环结构
循环结构示例
C#中常见的循环结构包括for、while、do-while和foreach,以下是具体示例和说明:
for循环
适用于已知循环次数的场景,语法为for(初始化; 条件; 迭代):
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"当前值: {i}");
}
输出:
当前值: 0
当前值: 1
...
当前值: 4
while循环
在条件为真时重复执行,适合不确定循环次数的情况:
int count = 0;
while (count < 3)
{
Console.WriteLine($"计数: {count}");
count++;
}
输出:
计数: 0
计数: 1
计数: 2
do-while循环
至少执行一次,之后检查条件:
int num = 5;
do
{
Console.WriteLine($"数值: {num}");
num--;
} while (num > 0);
输出:
数值: 5
数值: 4
...
数值: 1
foreach循环
遍历集合或数组元素:
string[] colors = { "红", "绿", "蓝" };
foreach (string color in colors)
{
Console.WriteLine(color);
}
输出:
红
绿
蓝
控制关键字
break:立即终止循环。continue:跳过当前迭代,进入下一次循环。
示例:
for (int i = 0; i < 10; i++)
{
if (i == 2) continue;
if (i == 5) break;
Console.WriteLine(i);
}
输出:
0
1
3
4
七.数组
数组的概念
数组是一种线性数据结构,用于存储相同类型元素的集合。元素通过索引(从0开始)访问,内存中连续存储,长度固定(声明后不可改变)。
数组的特点
- 固定长度:创建时需指定大小,无法动态扩展。
- 类型一致:所有元素必须为同一数据类型(如
int、string等)。 - 高效访问:通过索引直接访问元素,时间复杂度为 O(1)。
C# 数组示例
声明与初始化
// 声明并初始化一个整型数组
int[] numbers = new int[5]; // 长度为5,默认值为0
int[] numbers2 = { 1, 2, 3, 4, 5 }; // 直接赋值
// 字符串数组
string[] names = new string[] { "Alice", "Bob", "Charlie" };
访问与修改元素
int[] scores = { 90, 85, 78 };
Console.WriteLine(scores[0]); // 输出: 90
scores[1] = 88; // 修改索引1的元素
遍历数组
foreach (int score in scores)
{
Console.WriteLine(score);
}
// 或使用 for 循环
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine(scores[i]);
}
多维数组
// 二维数组
int[,] matrix = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
Console.WriteLine(matrix[1, 2]); // 输出: 6
// 遍历二维数组
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(1); col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
常用属性和方法
- Length:获取数组总长度。
- GetLength(int dimension):获取多维数组指定维度的长度。
- Array.Sort():排序数组。
- Array.Reverse():反转数组顺序。
int[] data = { 5, 3, 9, 1 };
Array.Sort(data); // 排序后: 1, 3, 5, 9
Array.Reverse(data); // 反转后: 9, 5, 3, 1
Array类的基本概念
Array类是C#中所有数组的基类,提供创建、操作、搜索和排序数组的方法。数组是固定大小的数据结构,用于存储相同类型的元素集合。Array类位于System命名空间下。
创建数组
使用Array类创建数组可以通过多种方式。以下示例展示几种常见方法:
// 使用new关键字创建一维数组
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
// 创建二维数组
int[,] matrix = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };
// 使用Array.CreateInstance方法创建数组
Array dynamicArray = Array.CreateInstance(typeof(string), 3);
dynamicArray.SetValue("A", 0);
dynamicArray.SetValue("B", 1);
dynamicArray.SetValue("C", 2);
常用属性和方法
Array类提供多个属性和方法来操作数组:
// Length属性获取数组总元素数
int[] numbers = { 10, 20, 30 };
Console.WriteLine(numbers.Length); // 输出3
// Rank属性获取数组维度
int[,] matrix = new int[2, 3];
Console.WriteLine(matrix.Rank); // 输出2
// Sort方法对数组排序
Array.Sort(numbers);
// IndexOf方法查找元素的索引
int index = Array.IndexOf(numbers, 20);
Console.WriteLine(index); // 输出1
遍历数组
可以通过循环结构遍历数组元素:
// 遍历一维数组
foreach (int num in numbers)
{
Console.WriteLine(num);
}
// 遍历多维数组
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();
}
数组复制
Array类提供多种复制数组的方法:
// 使用Clone方法浅拷贝
int[] clonedNumbers = (int[])numbers.Clone();
// 使用Copy方法复制部分元素
int[] dest = new int[3];
Array.Copy(numbers, dest, 2); // 复制前两个元素
// 使用CopyTo方法复制整个数组
numbers.CopyTo(dest, 0);
数组转换
可以通过多种方式转换数组类型:
// 转换数组类型
object[] objArray = { 1, "two", 3.0 };
string[] strArray = Array.ConvertAll(objArray, x => x.ToString());
// 使用AsEnumerable方法转换为IEnumerable
var enumerable = numbers.AsEnumerable();
注意事项
- 数组大小固定,创建后不能调整大小
- 多维数组与交错数组(数组的数组)不同
- Array类方法大多是静态方法,可以直接调用
- 访问超出范围的索引会抛出IndexOutOfRangeException
- 越界访问会抛出
IndexOutOfRangeException。 - 动态扩容需使用
List<T>集合类型。
八.方法
方法的基本概念
方法模块是编程中将代码组织成可重用块的方式。在C#中,方法也称为函数,用于封装特定功能或逻辑。方法通常包括访问修饰符、返回类型、方法名、参数列表和方法体。
声明方法的基本语法
访问修饰符 返回类型 方法名(参数列表)
{
// 方法体
return 返回值; // 可选
}
示例:
public int Add(int a, int b)
{
return a + b;
}
方法的调用
调用方法时需使用方法名并传递相应的参数。返回值可以赋给变量或直接使用。
int result = Add(5, 3);
Console.WriteLine(result); // 输出8
方法的参数类型
C#支持多种参数传递方式:
- 值参数:默认方式,传递参数的副本。
- 引用参数(ref):传递参数的内存地址,修改会影响原始变量。
- 输出参数(out):用于从方法返回多个值。
- 参数数组(params):允许传递可变数量的参数。
示例:
public void ModifyValues(ref int x, out int y, params int[] numbers)
{
x = x * 2;
y = 100;
foreach (var num in numbers)
{
Console.WriteLine(num);
}
}
方法的重载
方法重载允许在同一作用域内定义多个同名方法,只要它们的参数列表不同即可。
public int Add(int a, int b)
{
return a + b;
}
public double Add(double a, double b)
{
return a + b;
}
可选参数和命名参数
C#支持可选参数和命名参数,使方法调用更灵活。
public void PrintDetails(string name, int age = 30, string city = "Unknown")
{
Console.WriteLine($"Name: {name}, Age: {age}, City: {city}");
}
// 调用
PrintDetails("Alice"); // 使用默认参数
PrintDetails("Bob", city: "New York"); // 命名参数
静态方法
静态方法属于类而非实例,可直接通过类名调用。
public static class Utility
{
public static int Multiply(int a, int b)
{
return a * b;
}
}
// 调用
int product = Utility.Multiply(4, 5);
Lambda表达式和方法
Lambda表达式提供了一种简洁的方式来定义匿名方法。
Func<int, int, int> add = (a, b) => a + b;
int sum = add(2, 3); // 输出5
注:这是一种非常使用的方法,能极大的增加代码的简洁性,需要养成编程习惯。
&spm=1001.2101.3001.5002&articleId=149874910&d=1&t=3&u=60c968bbeab04709863406dc64816030)
1242

被折叠的 条评论
为什么被折叠?



