目录
第一部分:C# 基础
-
C# 简介
- C# 的历史与特点
- .NET 框架与 .NET Core/.NET 5+ 的关系
- 开发环境:Visual Studio、Visual Studio Code、Rider
-
第一个 C# 程序
- Hello World 程序
- 程序结构:命名空间、类、方法
- 编译与运行
-
变量与数据类型
- 基本数据类型:
int
,float
,double
,bool
,char
,string
- 变量声明与初始化
- 常量:
const
- 类型转换:隐式转换与显式转换
- 基本数据类型:
-
运算符
- 算术运算符:
+
,-
,*
,/
,%
- 比较运算符:
==
,!=
,>
,<
,>=
,<=
- 逻辑运算符:
&&
,||
,!
- 赋值运算符:
=
,+=
,-=
,*=
,/=
- 三元运算符:
? :
-
- 数组与字符串
-
- 数组:声明、初始化、访问、遍历
- 多维数组与锯齿数组
- 字符串操作:
string
,StringBuilder
break
,continue
,return
- 算术运算符:
运算符
算数运算符
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}"); // true
// 大于等于
Console.WriteLine($"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
后面括号中的变量)所支持的数据类型如下:
整数类型
包含 sbyte
、byte
、short
、ushort
、int
、uint
、long
、ulong
以及 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 <= 100):
grade = "优秀";
break;
case int n when (n >= 80 && n < 90):
grade = "良好";
break;
case int n when (n >= 70 && n < 80):
grade = "中等";
break;
case int n when (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 <= 100)
{
break;
}
Console.WriteLine("输入无效,请输入 0 到 100 之间的整数。");
}
string grade = score switch
{
>= 90 and <= 100 => "优秀",
>= 80 and < 90 => "良好",
>= 70 and < 80 => "中等",
>= 60 and < 70 => "及格",
_ => "不及格"
};
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();
}
}
类与对象的产生使用和组成规范
-
方法
- 方法的定义与调用
- 参数传递:值传递与引用传递(
ref
,out
) - 方法重载
-
访问修饰符
public
,private
,protected
,internal
- 封装的概念
-
继承
- 基类与派生类
base
关键字- 方法重写:
override
,virtual
-
多态
- 抽象类与抽象方法:
abstract
- 接口:
interface
- 接口与抽象类的区别
- 抽象类与抽象方法:
-
静态成员
- 静态字段与静态方法
- 静态类
static
关键字的使用场景