> 技术文档 > C#完整教程_c#教程

C#完整教程_c#教程

目录

第一部分:C# 基础

控制流

第二部分:面向对象编程(OOP)

第三部分:高级特性

第四部分:文件与 I/O 操作

第五部分:数据库操作

第六部分:图形用户界面(GUI)

第七部分:Web 开发

第八部分:游戏开发

第九部分:测试与调试

第十部分:部署与发布


第一部分:C# 基础

  1. C# 简介

    • C# 的历史与特点
    • .NET 框架与 .NET Core/.NET 5+ 的关系
    • 开发环境:Visual Studio、Visual Studio Code、Rider
  2. 第一个 C# 程序

    • Hello World 程序
    • 程序结构:命名空间、类、方法
    • 编译与运行
  3. 变量与数据类型

    • 基本数据类型:intfloatdoubleboolcharstring
    • 变量声明与初始化
    • 常量:const
    • 类型转换:隐式转换与显式转换
  4. 运算符

    • 算术运算符:+-*/%
    • 比较运算符:==!=><>=<=
    • 逻辑运算符:&&||!
    • 赋值运算符:=+=-=*=/=
    • 三元运算符:? :
      • 数组与字符串
        • 数组:声明、初始化、访问、遍历
        • 多维数组与锯齿数组
        • 字符串操作:stringStringBuilder

      句:breakcontinuereturn

运算符

算数运算符

1. 加法运算符(+

加法运算符用于将两个数值相加,也能用于拼接字符串。

using System;class Program{ static void Main() { int num1 = 5; int num2 = 3; int sum = num1 + num2; Console.WriteLine($\"两数相加的结果: {sum}\"); string str1 = \"Hello\"; string str2 = \" World\"; string combinedStr = str1 + str2; Console.WriteLine($\"字符串拼接结果: {combinedStr}\"); }}
2. 减法运算符(-

减法运算符用于从一个数值中减去另一个数值。

using System;class Program{ static void Main() { int num1 = 5; int num2 = 3; int difference = num1 - num2; Console.WriteLine($\"两数相减的结果: {difference}\"); }}
3. 乘法运算符(*

乘法运算符用于将两个数值相乘。

using System;class Program{ static void Main() { int num1 = 5; int num2 = 3; int product = num1 * num2; Console.WriteLine($\"两数相乘的结果: {product}\"); }}
4. 除法运算符(/

除法运算符用于将一个数值除以另一个数值。当操作数为整数时,结果会截断小数部分;若有一个操作数为浮点数,结果则为浮点数。

using System;class Program{ static void Main() { int intNum1 = 10; int intNum2 = 3; int intQuotient = intNum1 / intNum2; Console.WriteLine($\"整数相除的结果: {intQuotient}\"); double doubleNum1 = 10.0; double doubleNum2 = 3.0; double doubleQuotient = doubleNum1 / doubleNum2; Console.WriteLine($\"浮点数相除的结果: {doubleQuotient}\"); }}
5. 取模运算符(%

取模运算符用于计算两个数值相除后的余数。

using System;class Program{ static void Main() { int num1 = 10; int num2 = 3; int remainder = num1 % num2; Console.WriteLine($\"两数取模的结果: {remainder}\"); }}
6. 自增运算符(++

自增运算符用于将变量的值加 1。可分为前缀自增(++variable)和后缀自增(variable++)。前缀自增会先将变量的值加 1,再返回变量的值;后缀自增则先返回变量的值,再将变量的值加 1。

using System;class Program{ static void Main() { int num = 5; int prefixIncrement = ++num; Console.WriteLine($\"前缀自增后的结果: {prefixIncrement}\"); num = 5; int postfixIncrement = num++; Console.WriteLine($\"后缀自增后的结果: {postfixIncrement}\"); Console.WriteLine($\"后缀自增后变量的值: {num}\"); }}
7. 自减运算符(--

自减运算符用于将变量的值减 1。同样分为前缀自减(--variable)和后缀自减(variable--)。前缀自减先将变量的值减 1,再返回变量的值;后缀自减先返回变量的值,再将变量的值减 1。

using System;class Program{ static void Main() { int num = 5; int prefixDecrement = --num; Console.WriteLine($\"前缀自减后的结果: {prefixDecrement}\"); num = 5; int postfixDecrement = num--; Console.WriteLine($\"后缀自减后的结果: {postfixDecrement}\"); Console.WriteLine($\"后缀自减后变量的值: {num}\"); }}

布尔逻辑运算符

在 C# 里,布尔逻辑运算符用于对布尔类型的值进行操作,其运算结果同样是布尔类型(true 或者 false)。下面为你详细介绍 C# 中常见的布尔逻辑运算符,同时给出相应的代码示例。

1. 逻辑与运算符(&&

当两个操作数都为 true 时,逻辑与运算符的运算结果才为 true;只要有一个操作数为 false,结果就为 false。它采用短路求值的方式,也就是说,若第一个操作数为 false,则不会再计算第二个操作数。

using System;class Program{ static void Main() { bool condition1 = true; bool condition2 = false; bool result = condition1 && condition2; Console.WriteLine($\"逻辑与运算结果: {result}\"); }}
2. 逻辑或运算符(||

只要两个操作数中有一个为 true,逻辑或运算符的运算结果就为 true;只有当两个操作数都为 false 时,结果才为 false。它也采用短路求值的方式,若第一个操作数为 true,则不会再计算第二个操作数。

using System;class Program{ static void Main() { bool condition1 = true; bool condition2 = false; bool result = condition1 || condition2; Console.WriteLine($\"逻辑或运算结果: {result}\"); }}
3. 逻辑非运算符(!

逻辑非运算符是一元运算符,它会对操作数的布尔值取反。若操作数为 true,则结果为 false;若操作数为 false,则结果为 true

using System;class Program{ static void Main() { bool condition = true; bool result = !condition; Console.WriteLine($\"逻辑非运算结果: {result}\"); }}
4. 逻辑异或运算符(^

当两个操作数的布尔值不同时,逻辑异或运算符的运算结果为 true;若两个操作数的布尔值相同,则结果为 false

using System;class Program{ static void Main() { bool condition1 = true; bool condition2 = false; bool result = condition1 ^ condition2; Console.WriteLine($\"逻辑异或运算结果: {result}\"); }}
5. 按位逻辑与运算符(&)和按位逻辑或运算符(|

& 和 | 既可以用作按位运算符处理整数类型,也能当作逻辑运算符处理布尔类型。与 && 和 || 不同的是,它们不会进行短路求值,也就是说,无论第一个操作数的结果如何,都会对第二个操作数进行计算。

using System;class Program{ static void Main() { bool condition1 = true; bool condition2 = false; bool andResult = condition1 & condition2; bool orResult = condition1 | condition2; Console.WriteLine($\"按位逻辑与运算结果: {andResult}\"); Console.WriteLine($\"按位逻辑或运算结果: {orResult}\"); }}

位运算符

        在 C# 中,位运算符用于对整数类型的操作数按二进制位进行操作。下面为你详细介绍常见的位运算符及其用法,并给出相应的代码示例。

1. 按位与运算符(&

        按位与运算符会对两个操作数的对应二进制位进行与运算。只有当两个对应位都为 1 时,结果的该位才为 1,否则为 0。

using System;class Program{ static void Main() { int num1 = 5; // 二进制: 0101 int num2 = 3; // 二进制: 0011 int result = num1 & num2; // 二进制: 0001,十进制: 1 Console.WriteLine($\"按位与结果: {result}\"); }}
2. 按位或运算符(|

        按位或运算符会对两个操作数的对应二进制位进行或运算。只要两个对应位中有一个为 1,结果的该位就为 1,只有当两个对应位都为 0 时,结果的该位才为 0。

using System;class Program{ static void Main() { int num1 = 5; // 二进制: 0101 int num2 = 3; // 二进制: 0011 int result = num1 | num2; // 二进制: 0111,十进制: 7 Console.WriteLine($\"按位或结果: {result}\"); }}
3. 按位异或运算符(^

        按位异或运算符会对两个操作数的对应二进制位进行异或运算。当两个对应位不同时,结果的该位为 1,相同时为 0。

using System;class Program{ static void Main() { int num1 = 5; // 二进制: 0101 int num2 = 3; // 二进制: 0011 int result = num1 ^ num2; // 二进制: 0110,十进制: 6 Console.WriteLine($\"按位异或结果: {result}\"); }}
4. 按位取反运算符(~

        按位取反运算符是一元运算符,它会对操作数的每个二进制位进行取反操作,即 0 变为 1,1 变为 0。

using System;class Program{ static void Main() { int num = 5; // 二进制: 0101 int result = ~num; // 二进制补码表示:先取反得到 1010,再考虑符号位等,最终结果为 -6 Console.WriteLine($\"按位取反结果: {result}\"); }}
5. 左移运算符(<<

        左移运算符会将操作数的二进制位向左移动指定的位数,右边空出的位用 0 填充。左移 n 位相当于将该数乘以 2 的 n 次方。

using System;class Program{ static void Main() { int num = 5; // 二进制: 0101 int result = num << 2; // 二进制: 010100,十进制: 20 Console.WriteLine($\"左移 2 位结果: {result}\"); }}
6. 右移运算符(>>

        右移运算符会将操作数的二进制位向右移动指定的位数。对于无符号数,左边空出的位用 0 填充;对于有符号数,左边空出的位用符号位填充(正数补 0,负数补 1)。右移 n 位相当于将该数除以 2 的 n 次方(向下取整)。

using System;class Program{ static void Main() { int num = 20; // 二进制: 010100 int result = num >> 2; // 二进制: 000101,十进制: 5 Console.WriteLine($\"右移 2 位结果: {result}\"); }}

关系运算符 

using System;class Program{ static void Main() { int a = 10; int b = 20; // 等于 Console.WriteLine($\"a == b: {a == b}\"); // false // 不等于 Console.WriteLine($\"a != b: {a != b}\"); // true // 大于 Console.WriteLine($\"a > b: {a > b}\"); // false // 小于 Console.WriteLine($\"a < b: {a = b: {a >= b}\"); // false // 小于等于 Console.WriteLine($\"a <= b: {a <= b}\"); // true }}

c#运算符优先级

using System;class Program{ static void Main() { int a = 5; int b = 3; int c = 2; // 先计算乘法,再计算加法 int result1 = a + b * c; Console.WriteLine($\"a + b * c 的结果: {result1}\"); // 先计算括号内的加法,再计算乘法 int result2 = (a + b) * c; Console.WriteLine($\"(a + b) * c 的结果: {result2}\"); // 逻辑与运算符优先级高于逻辑或运算符 bool condition1 = true || false && false; Console.WriteLine($\"true || false && false 的结果: {condition1}\"); // 加括号改变运算顺序 bool condition2 = (true || false) && false; Console.WriteLine(\"(true || false) && false 的结果: {condition2}\"); }}

三元运算符

控制流

        控制流是编程中用于控制程序执行顺序的机制,主要包括条件语句、循环语句和跳转语句。

条件语句

        条件语句用于根据条件决定是否执行某段代码。

1.1 if 语句
int age = 18;if (age >= 18){ Console.WriteLine(\"You are an adult.\");}
1.2 if-else 语句
int age = 16;if (age >= 18){ Console.WriteLine(\"You are an adult.\");}else{ Console.WriteLine(\"You are a minor.\");}
1.3 if-else if-else 语句
int score = 85;if (score >= 90){ Console.WriteLine(\"Grade: A\");}else if (score >= 80){ Console.WriteLine(\"Grade: B\");}else if (score >= 70){ Console.WriteLine(\"Grade: C\");}else{ Console.WriteLine(\"Grade: D\");}
1.4 switch 语句

在 C# 里,switch 语句的控制表达式(也就是 switch 后面括号中的变量)所支持的数据类型如下:

整数类型

包含 sbytebyteshortushortintuintlongulong 以及 char 类型。这些类型的值可以直接用在 switch 语句中。

using System;class Program{ static void Main() { int number = 2; switch (number) { case 1: Console.WriteLine(\"The number is 1.\"); break; case 2: Console.WriteLine(\"The number is 2.\"); break; default: Console.WriteLine(\"The number is neither 1 nor 2.\"); break; } }}

枚举类型

自定义的枚举类型也能在 switch 语句里使用。

using System;// 定义一个枚举类型enum Weekday{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}class Program{ static void Main() { Weekday today = Weekday.Monday; switch (today) { case Weekday.Monday: Console.WriteLine(\"It\'s Monday.\"); break; case Weekday.Tuesday: Console.WriteLine(\"It\'s Tuesday.\"); break; // 其他情况可依次添加 default: Console.WriteLine(\"It\'s another day.\"); break; } }}

字符串类型

从 C# 7.0 起,switch 语句支持字符串类型。

using System;class Program{ static void Main() { string color = \"Red\"; switch (color) { case \"Red\": Console.WriteLine(\"The color is red.\"); break; case \"Blue\": Console.WriteLine(\"The color is blue.\"); break; default: Console.WriteLine(\"The color is neither red nor blue.\"); break; } }}

可为空值类型

如果上述支持的类型是可为空值类型(例如 int?string? 等),同样可以在 switch 语句中使用。

using System;class Program{ static void Main() { int? nullableNumber = 2; switch (nullableNumber) { case 1: Console.WriteLine(\"The number is 1.\"); break; case 2: Console.WriteLine(\"The number is 2.\"); break; case null: Console.WriteLine(\"The number is null.\"); break; default: Console.WriteLine(\"The number is neither 1 nor 2.\"); break; } }}

模式匹配(C# 7.0 及更高版本)

从 C# 7.0 开始,switch 语句支持模式匹配,能对更多类型和条件进行匹配。

using System;class Program{ static void Main() { object obj = 2; switch (obj) { case int i when i < 5: Console.WriteLine($\"The integer is less than 5: {i}\"); break; case string s: Console.WriteLine($\"The string is: {s}\"); break; default: Console.WriteLine(\"The object is of another type.\"); break; } }}

不支持的类型 

浮点类型

float 和 double 类型不适合用于 switch 语句,这是因为浮点数在计算机中是以二进制近似表示的,存在精度问题。例如,两个理论上相等的浮点数在计算机中可能由于精度误差而不相等,这样就无法准确匹配 case 标签。

using System;class Program{ static void Main() { double num = 0.1 + 0.2; // 由于精度问题,这里的比较可能不会按预期工作 switch (num) { case 0.3: Console.WriteLine(\"The number is 0.3\"); break; default: Console.WriteLine(\"The number is not 0.3\"); break; } }}

在这个例子中,尽管数学上 0.1 + 0.2 等于 0.3,但由于浮点数精度问题,switch 语句可能不会匹配到 case 0.3

引用类型(除字符串)

一般的引用类型(如自定义类、数组等)不支持直接用于 switch 语句,因为引用类型比较的是引用地址而非值本身。不过,字符串类型是个例外,从 C# 7.0 开始支持在 switch 语句中使用。

using System;class MyClass{ public int Value { get; set; }}class Program{ static void Main() { MyClass obj1 = new MyClass { Value = 1 }; MyClass obj2 = new MyClass { Value = 1 }; // 以下代码会报错,因为 MyClass 类型不能直接用于 switch 语句 // switch (obj1) // { // case obj2: // Console.WriteLine(\"Objects are equal\"); // break; // default: // Console.WriteLine(\"Objects are not equal\"); // break; // } }}

布尔类型以外的逻辑类型

除了布尔类型,像 bool?(可为空的布尔类型)可以在 switch 中使用外,其他逻辑相关的自定义类型如果没有合适的转换机制,也不能直接用于 switch 语句。

动态类型

dynamic 类型也不能直接用于 switch 语句,因为在编译时无法确定 dynamic 类型的具体值,switch 语句需要在编译时确定可能的 case 标签。

using System;class Program{ static void Main() { dynamic value = 1; // 以下代码会报错,因为 dynamic 类型不能用于 switch 语句 // switch (value) // { // case 1: // Console.WriteLine(\"Value is 1\"); // break; // default: // Console.WriteLine(\"Value is not 1\"); // break; // } }}

示例 1:简单的 switch 语句

int day = 3;switch (day){ case 1: Console.WriteLine(\"Monday\"); break; case 2: Console.WriteLine(\"Tuesday\"); break; case 3: Console.WriteLine(\"Wednesday\"); break; default: Console.WriteLine(\"Invalid day\"); break;}

输出:

Wednesday

示例 2:多个 case 共享代码块

int month = 2;switch (month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: Console.WriteLine(\"31 days\"); break; case 4: case 6: case 9: case 11: Console.WriteLine(\"30 days\"); break; case 2: Console.WriteLine(\"28 or 29 days\"); break; default: Console.WriteLine(\"Invalid month\"); break;}

输出:

28 or 29 days

示例 3:switch 与字符串

string fruit = \"Apple\";switch (fruit){ case \"Apple\": Console.WriteLine(\"It\'s an apple.\"); break; case \"Banana\": Console.WriteLine(\"It\'s a banana.\"); break; default: Console.WriteLine(\"Unknown fruit.\"); break;}

输出:

It\'s an apple.

switch 语句与模式匹配

using System; class Program{ static void Main(string[] args) { int score; Console.Write(\"请输入学生的分数:\"); score = Convert.ToInt32(Console.ReadLine()); string grade; switch (score) { case int n when (n >= 90 && n = 80 && n = 70 && n = 60 && n < 70): grade = \"及格\"; break; default: grade = \"不及格\"; break; } Console.WriteLine(\"学生的成绩分类为:\" + grade); }}

switch 表达式(C#8.0及以上)

using System;class Program{ static void Main(string[] args) { int score; while (true) { Console.Write(\"请输入学生的分数:\"); if (int.TryParse(Console.ReadLine(), out score) && score >= 0 && score = 90 and  \"优秀\", >= 80 and  \"良好\", >= 70 and  \"中等\", >= 60 and  \"及格\", _ => \"不及格\" }; Console.WriteLine(\"学生的成绩分类为:\" + grade); }}

循环语句

        循环语句用于重复执行某段代码,直到满足特定条件。

2.1 for 循环
for (int i = 0; i < 5; i++){ Console.WriteLine(\"Iteration: \" + i);}
2.2 while 循环
int i = 0;while (i < 5){ Console.WriteLine(\"Iteration: \" + i); i++;}
2.3 do-while 循环
int i = 0;do{ Console.WriteLine(\"Iteration: \" + i); i++;} while (i < 5);
2.4 foreach 循环
string[] fruits = { \"Apple\", \"Banana\", \"Cherry\" };foreach (string fruit in fruits){ Console.WriteLine(fruit);}

跳转语句

        跳转语句用于改变程序的执行顺序。

3.1 break 语句
  • 用于退出循环或 switch 语句。
for (int i = 0; i < 10; i++){ if (i == 5) { break; // 退出循环 } Console.WriteLine(\"Iteration: \" + i);}
3.2 continue 语句
  • 用于跳过当前循环的剩余部分,直接进入下一次循环。
for (int i = 0; i < 10; i++){ if (i % 2 == 0) { continue; // 跳过偶数 } Console.WriteLine(\"Iteration: \" + i);}
3.3 return 语句
  • 用于从方法中返回值并退出方法。
int Add(int a, int b){ return a + b;}int result = Add(3, 5); // result = 8
3.4 goto 语句
  • 用于跳转到指定的标签(不推荐使用,容易导致代码混乱)。
int i = 0;start:if (i < 5){ Console.WriteLine(\"Iteration: \" + i); i++; goto start; // 跳转到 start 标签}

第二部分:面向对象编程(OOP)

类与对象

通过程序观察初步认识面向对象编程

using System;// 定义一个简单的类class Person{ // 字段 private string name; private int age; // 构造函数 public Person(string name, int age) { this.name = name; this.age = age; } // 方法 public void Introduce() { Console.WriteLine($\"我叫 {name},今年 {age} 岁。\"); }}class Program{ static void Main() { // 创建对象 Person person = new Person(\"张三\", 25); // 调用对象的方法 person.Introduce(); }}

类与对象的产生使用和组成规范 

  1. 方法

    • 方法的定义与调用
    • 参数传递:值传递与引用传递(refout
    • 方法重载
  2. 访问修饰符

    • publicprivateprotectedinternal
    • 封装的概念
  3. 继承

    • 基类与派生类
    • base 关键字
    • 方法重写:overridevirtual
  4. 多态

    • 抽象类与抽象方法:abstract
    • 接口:interface
    • 接口与抽象类的区别
  5. 静态成员

    • 静态字段与静态方法
    • 静态类
    • static 关键字的使用场景