C#简介(从入门到精通)
一、发展历史
C#的主要作者是丹麦计算机科学家安德斯·海尔斯伯格(Anders Hejlsberg),他是该语言的首席设计师,同时也是Turbo Pascal(Pascal 语言编译器)、Delphi(由 Borland(后被 Embarcadero 收购)开发的面向对象编程语言与集成开发环境(IDE))和TypeScript(由微软开发的开源编程语言,JavaScript 的超级版)的创造者,以及.NET框架的创立者。
C#(读作 “C Sharp”)是由微软开发的面向对象编程语言,基于.NET 框架,旨在结合灵活性、性能和生产力。其发展历程如下:
1. 起源与早期版本(2000-2005)
-
2000 年:C# 1.0 随.NET Framework 1.0 发布,设计灵感源自 C++、Java 和 Delphi,目标是简化企业级开发。
-
2005 年:C# 2.0 引入泛型、匿名方法、可空类型和迭代器,增强类型安全和代码复用性。
2. 功能扩展(2007-2010)
-
2007 年:C# 3.0 推出 Lambda 表达式、LINQ(语言集成查询)、自动属性和匿名类型,大幅提升数据查询效率。
-
2010 年:C# 4.0 支持动态类型(
dynamic
)、命名参数、可选参数和 COM 互操作性,增强灵活性。
3. 异步与并行编程(2012-2015)
-
2012 年:C# 5.0 引入
async/await
异步编程模型,简化异步操作的编写。 -
2015 年:C# 6.0 增加异常过滤器、字典初始化语法、空条件运算符(
?.
)和 nameof 表达式,提升代码可读性。
4. 现代特性与跨平台(2017 - 至今)
-
2017 年:C# 7.0 支持模式匹配、元组、局部函数和二进制字面量,增强代码表达力。
-
2019 年:C# 8.0 引入 nullable 引用类型、异步流、范围运算符(
..
)和模式匹配增强,配合.NET Core 实现跨平台开发。 -
2020 年:C# 9.0 推出记录类型(
record
)、顶级程序集、模式匹配改进和 init 只读属性。 -
2022 年:C# 10.0 支持源生成器、文件范围命名空间、集合表达式改进和原始字符串字面量。
-
2023 年:C# 11.0 新增泛型数学、集合切片、原始字符串内插和
required
修饰符,持续优化开发体验。
关键发展背景:
-
随着.NET 从 Windows 平台扩展到.NET Core(2016)和统一的.NET(2020),C# 成为跨平台开发(Windows、macOS、Linux)的核心语言。
-
社区驱动的改进通过.NET 基金会持续推进,例如通过 RFC(Request for Comments)收集开发者反馈。
二、开发工具
C# 开发工具覆盖从 IDE 到命令行,适配不同开发场景:
1. 集成开发环境(IDE)
Visual Studio
Visual Studio Code(VS Code)
JetBrains Rider
工具 | 特点 | 适用场景 |
---|---|---|
Visual Studio | 微软官方全功能 IDE,支持调试、代码分析、UI 设计器,集成.NET 生态工具。 | 企业级应用、Windows 桌面开发 |
Visual Studio Code(VS Code) | 轻量级跨平台编辑器,通过 C# 扩展包支持智能提示、调试和代码重构。 | 跨平台开发、快速原型设计 |
JetBrains Rider | 跨平台 IDE,提供强大的代码分析、重构工具和多语言支持(如 C#、Kotlin)。 | 专业开发者、复杂项目 |
2. 命令行工具
-
.NET CLI:跨平台命令行接口,用于创建项目、编译代码和管理依赖(如
dotnet new
、dotnet build
) -
MSBuild:微软构建平台,通过
.csproj
项目文件定义编译流程,支持自动化构建和 CI/CD
3. 辅助工具
-
Resharper(VS 插件):代码分析、重构建议和代码生成,提升开发效率。
-
NUnit/MSTest/xUnit:单元测试框架,支持自动化测试和断言。
-
Fiddler/Postman:接口调试工具,适用于 C# 开发的 Web 服务测试。
.NET 技术栈核心组件
1. .NET Framework 与 .NET Core
-
.NET Framework 传统 Windows 平台的运行时环境,包含:
-
CLR (Common Language Runtime):底层运行时,负责内存管理、垃圾回收等。
-
FCL (Framework Class Library):基础类库,提供如
System.IO
、System.Net
等功能。 -
支持 Windows Forms、ASP.NET等应用模型。
-
-
.NET Core/.NET 5+ 跨平台(Windows/macOS/Linux)的现代框架,统一了.NET Framework、.NET Core 和 Xamarin,支持:
-
控制台、Web、移动(MAUI)、云服务等应用类型。
-
模块化依赖管理(NuGet)和更小的部署包。
-
2. C# 与公共类型系统 (CTS)
-
C# 语言:.NET 生态的主要编程语言,语法简洁,支持面向对象、泛型、LINQ 等特性。
-
CTS (Common Type System):.NET 的类型规范,定义了:
-
基础类型(如
int
映射到System.Int32
)。 -
类型兼容性规则,确保不同语言(C#、VB.NET等)间的互操作性。
-
示例:
int a = 10; // C#语法糖,实际对应System.Int32
Int32 b = 20; // 显式使用CTS类型名
string s = "hello"; // C#字符串(映射到System.String)
String s2 = "HELLO"; // 等效于string(CTS类型名)
3. CLR 与 JIT 编译
-
CLR (Common Language Runtime):.NET 的运行时环境,负责:
-
加载和执行程序集(IL 代码)。
-
通过 JIT(Just-In-Time)编译器将 IL 转换为机器码。
-
提供内存管理、类型安全检查等服务。
-
-
JIT 工作流程:
C#源码 → 编译器(csc) → IL中间语言(.dll/.exe) → JIT → 机器码(CPU执行)
4. CTS 与 CLS
-
CTS (Common Type System):定义所有.NET 语言必须遵循的类型规范。
-
CLS (Common Language Specification):CTS 的子集,确保语言间互操作性(如 C# 与VB.NET)。
三、基础语法知识
第一个 C# 程序解析
代码结构
using System; // 引入System命名空间
namespace demo2 // 命名空间:组织代码的逻辑容器
{public class Program // 公共类:程序入口点{public static void Main() // 程序主方法(入口点){Console.WriteLine("Hello C#"); // 输出到控制台Console.ReadKey(); // 等待用户按键,防止窗口自动关闭}}
}
编译流程
-
源码 (.cs) → IL 中间语言 (.exe) → 机器码
-
手动编译步骤
(需配置环境变量):
# 1. 进入源码目录 cd C:\Users\YourName\Documents # 2. 使用csc编译器生成.exe csc HelloWorld.cs # 3. 运行程序 HelloWorld.exe
编译工具与环境配置
1. csc 编译器
-
路径:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe
(64 位系统的.NET Framework 4.0 版本)
2. 环境变量配置
-
旧方法:手动将
csc.exe
路径添加到系统PATH
变量。 -
现代开发:安装 Visual Studio 后自动配置环境变量,支持直接使用
csc
命令。
DOS 命令基础
命令 | 作用 | 示例 |
---|---|---|
cd | 切换目录 | cd C:\Projects |
dir | 显示当前目录内容 | dir |
cls | 清屏 | cls |
csc | 编译 C# 源码 | csc Program.cs |
命名空间与标识符规范
命名空间(Namespace)
-
逻辑分组代码,避免命名冲突。
-
示例:
System.Console
中的System
是命名空间。
标识符规范
元素 | 命名规范 | 示例 |
---|---|---|
类 / 命名空间 | PascalCase | CustomerManager |
方法 / 属性 | PascalCase | GetUserInfo() |
变量 / 参数 | camelCase | userName |
常量 | 全大写 + 下划线 | MAX_CONNECTIONS |
核心类与方法解析
1. Console 类
-
位于
System //命名空间,提供控制台输入 / 输出功能: Console.WriteLine("文本"); // 输出并换行 Console.Write("不换行"); // 输出不换行 Console.ReadLine(); // 读取用户输入(按回车结束)
2. Main 方法
-
程序入口点,签名必须为:
public static void Main() // 无参数版本 public static int Main() // 返回int表示退出代码 public static void Main(string[] args) // 接收命令行参数
语句、块与空白
-
语句:一行可执行代码(如
int a = 10;
)。 -
块:用
{}
包裹的语句组(如方法体)。 -
空白:空格、制表符、换行符,用于提高代码可读性,编译器会忽略。
C# 标识符规则
标识符用于命名类、变量、函数等用户定义的元素,命名需遵循以下规则:
-
字符组成:由字母、数字、下划线(
_
)组成。 -
开头限制:必须以字母、下划线或
@
开头,不能以数字开头。 -
特殊符号:禁止包含空格或特殊符号(如
?、+、!、#
等)。 -
关键字冲突:不能是 C# 关键字,但若添加
@
前缀可作为标识符(如@if
)。 -
大小写敏感:严格区分大小写(如
UserAge
和userAge
是不同标识符)。 -
命名规范:建议 “见名知意”,例如用
userName
表示用户名。
C# 关键字
C# 关键字分为保留关键字和上下文关键字,以下是常见类型:
保留关键字(不可直接作为标识符)
abstract | as | base | bool | break | byte | case |
---|---|---|---|---|---|---|
catch | char | checked | class | const | continue | decimal |
default | delegate | do | double | else | enum | event |
if | int | interface | namespace | new | public | static |
try | void | while | ... | ... | ... | ... |
上下文关键字(仅在特定上下文有特殊含义)
| add | alias | ascending| dynamic | from | get | | global | group | into | join | let | orderby | | partial | remove | select | set | where | yield |
变量与常量
变量
-
定义格式:
数据类型 变量名;
(如int age;
)。 -
赋值方式:通过
=
运算符赋值(如age = 18;
),可声明时直接赋值(如string name = "张三";
)。 -
注意事项:
-
变量名不可重复声明。
-
必须初始化(赋值)后才能使用。
-
可同时定义多个同类型变量(如
int a, b, c;
)。
-
常量
-
定义格式:使用
const
关键字,值在编译阶段确定且不可修改。
const double PI = 3.1415926; // 正确 // PI = 3.14; // 错误:常量不可修改
控制台常用方法
方法 | 描述 |
---|---|
WriteLine() | 输出内容并换行(如 Console.WriteLine("Hello World!"); )。 |
Write() | 输出内容不换行(如 Console.Write("No newline"); )。 |
ReadKey() | 等待用户输入单个字符,返回输入的键(常用于暂停程序)。 |
ReadLine() | 等待用户输入一行文本,返回字符串(需按回车键确认)。 |
Beep() | 播放系统提示音(如 Console.Beep(2000, 800); :频率 2000Hz,持续 800ms)。 |
Clear() | 清空控制台窗口内容。 |
控制台属性(修改颜色)
Console.BackgroundColor = ConsoleColor.Red; // 设置背景色为红色 Console.ForegroundColor = ConsoleColor.Yellow; // 设置字体颜色为黄色 Console.WriteLine("红色背景+黄色字体");
1.数据类型
C# 数据类型分为值类型和引用类型:
值类型(直接存储数据值)
类型 | 描述 | 示例 | 默认值 |
---|---|---|---|
整数 | 有符号 / 无符号整数 | int age = 18; byte score = 90; | 0 |
浮点数 | 单精度 / 双精度小数 | float price = 9.9f; double pi = 3.14; | 0.0 |
布尔 | 逻辑值(真 / 假) | bool isReady = true; | false |
字符 | 单个 Unicode 字符 | char gender = '男'; | \0 |
字符串 | 字符序列(引用类型) | string name = "李四"; | null |
引用类型(存储数据引用)
-
对象(
object
):所有类型的基类,可存储任意类型数据(如object obj = "文本"; obj = 123;
)。 -
动态类型(
dynamic
):类型检查在运行时进行,灵活性高但可能引发运行时错误。
1.1 值类型(Value Types)
直接存储数据值,分配在栈内存中。常见值类型:
int age = 25; // 整数(32位)
double height = 1.75; // 双精度浮点数
bool isStudent = true; // 布尔值
char grade = 'A'; // 字符(Unicode)
decimal salary = 5000.00m; // 高精度小数(金融计算)
特殊值类型:
-
枚举(enum):定义命名常量集合:
enum Color { Red, Green, Blue } Color favorite = Color.Blue;
-
结构体(struct):轻量级数据结构,可包含字段和方法:
struct Point {public int X;public int Y;public double Distance() => Math.Sqrt(X*X + Y*Y); }
1.2 引用类型(Reference Types)
存储对象引用,实际数据在堆内存中。常见引用类型:
string name = "Doubao"; // 字符串(不可变)
object obj = 42; // 基类型,可引用任何对象
int[] numbers = { 1, 2, 3 }; // 数组
动态类型(dynamic):运行时确定类型(C# 4.0+):
dynamic dynamicVar = "Hello";
dynamicVar = 123; // 合法,运行时绑定
1.3 可空类型(Nullable Types)
处理值类型可能为null
的场景(值类型默认不可为null
):
int? nullableInt = null; // 可空int
if (nullableInt.HasValue) {Console.WriteLine(nullableInt.Value);
} else {Console.WriteLine("Value is null");
}
// 空合并运算符(??)
int result = nullableInt ?? 0; // 若nullableInt为null,赋值0
作业:变量定义练习
根据描述定义合适的变量(注意数据类型和命名规范):
描述 | 变量名 | 数据类型 | 示例值 |
---|---|---|---|
苹果的个数 | appleCount | int | 5 |
头发的长度 | hairLength | double | 15.5 |
眼睛的颜色 | eyeColor | string | "黑色" |
大象的重量 | elephantWeight | double | 3000.5 |
现在的季节 | currentSeason | string | "夏季" |
现在的天气 | currentWeather | string | "晴" |
手指的个数 | fingerCount | int | 10 |
空调的温度 | airConditionTemp | int | 24 |
现在放学没有 | isAfterSchool | bool | true |
明天下雨不下 | willRainTomorrow | bool | false |
水的重量 | waterWeight | double | 50.2 |
鞋的码数 | shoeSize | int | 42 |
女朋友的名字 | girlfriendName | string | "小美" |
有没有女朋友 | hasGirlfriend | bool | true |
餐厅名字 | restaurantName | string | "幸福餐厅" |
学生的学号 | studentId | string | "20230101" |
电话号码 | phoneNumber | string | "13812345678" |
一句话 | sentence | string | "C# 学习很有趣!" |
扩展知识:计算机存储单位
-
基本单位:
-
位(bit):最小存储单位,只能是
0
或1
。 -
字节(Byte, B):基本存储单位,
1 Byte = 8 bit
,一个英文字符占1 Byte
,一个汉字占2 Byte
。
-
-
换算关系:
1 B = 8 bit 1 KB = 2^10 B = 1024 B 1 MB = 2^10 KB = 2^20 B 1 GB = 2^10 MB = 2^30 B 1 TB = 2^10 GB = 2^40 B 1 PB = 2^10 TB = 2^50 B 1 EB = 2^10 PB = 2^60 B 1 ZB = 2^10 EB = 2^70 B 1 YB = 2^10 ZB = 2^80 B
-
注意:
-
十进制单位(GB)与二进制单位(GiB)易混淆,计算机实际按二进制换算。
-
大文件存储(如视频、硬盘容量)常用 GB、TB 表示。
-
*名称* | *简写* | *换算* |
---|---|---|
比特(Bit) | bit/b | |
字节(Byte) | B | 1B=8bit |
半字节(Nibble) | N | 1B=8N |
千字节(Kilobyte) | KB | 1KB=2^10 B =1024B |
兆字节(Megabyte) | MB | 1MB=2^10 KB =2^20 B |
吉字节(Gigabyte) | GB | 1GB=2^10 MB =2^30 B |
太字节(Terabyte) | TB | 1TB=2^10 GB =2^40 B |
拍字节(Petabyte) | PB | 1PB=2^10 TB =2^50 B |
艾字节(Exabyte) | EB | 1EB=2^10 PB =2^60 B |
泽字节(Zettabyte) | ZB | 1ZB=2^10 EB =2^70 B |
尧字节(Yottabyte) | YB | 1YB=2^10 ZB =2^80 B |
运算符概述
运算符是用于执行特定数学或逻辑操作的符号。通过组合变量、常量和运算符,可以构成表达式(如 a + b
、true && false
)。表达式的运算结果具有值类型。
算术运算符
运算符 | 描述 | 示例 | 注意事项 |
---|---|---|---|
+ | 加法 | 5 + 3 → 8 | 字符串拼接时使用 + (如 "a" + "b" → "ab" ) |
- | 减法 | 5 - 3 → 2 | |
* | 乘法 | 5 * 3 → 15 | |
/ | 除法 | 5 / 3 → 1 (整数) | 整数相除结果为整数(舍弃小数部分) |
% | 取余(模) | 5 % 3 → 2 | 除数不能为 0 (如 10 % 0 会报错) |
示例代码:
int a = 10;
int b = 3;
Console.WriteLine(a / b); // 输出 3(整数除法)
Console.WriteLine(a % b); // 输出 1(取余)
// 字符串拼接
string name = "张三";
int age = 20;
Console.WriteLine(name + "今年" + age + "岁"); // 输出:张三今年20岁
赋值运算符
运算符 | 等价形式 | 示例 |
---|---|---|
= | 直接赋值 | int a = 10; |
+= | a = a + n | a += 5 → a = 15 |
-= | a = a - n | a -= 3 → a = 7 |
*= | a = a * n | a *= 2 → a = 20 |
/= | a = a / n | a /= 5 → a = 2 |
%= | a = a % n | a %= 3 → a = 1 |
自增 / 自减运算符(++
/--
)
-
后置自增(
a++
):先返回值,再自增。 -
前置自增(
++a
):先自增,再返回值。
示例:
int a = 5;
int b = a++; // b = 5(先赋值,后a自增为6)
int c = ++a; // c = 7(a先自增为7,再赋值给c)
Console.WriteLine(a); // 输出 7
Console.WriteLine(b); // 输出 5
Console.WriteLine(c); // 输出 7
比较运算符(返回bool
类型)
运算符 | 描述 | 示例 |
---|---|---|
< | 小于 | 5 < 3 → false |
> | 大于 | 5 > 3 → true |
<= | 小于等于 | 5 <= 5 → true |
>= | 大于等于 | 5 >= 3 → true |
== | 等于 | 5 == 3 → false |
!= | 不等于 | 5 != 3 → true |
逻辑运算符(操作bool
值)
运算符 | 描述 | 示例 |
---|---|---|
&& | 短路与(两边为真才为真) | true && false → false |
|| | 短路或(一边为真即为真) | true || false →true |
! | 非(取反) | !true → false |
& | 逻辑与(不短路) | true & false → false |
| | 逻辑或(不短路) | true | false →true |
短路逻辑:
-
&&
:若左侧为false
,右侧不执行。 -
||
:若左侧为true
,右侧不执行。
示例:
int a = 5;
bool result = (a > 10) && (++a > 0); // a>10为false,右侧不执行
Console.WriteLine(a); // 输出 5(a未自增)
bool result2 = (a < 10) || (++a > 0); // a<10为true,右侧不执行
Console.WriteLine(a); // 输出 5(a未自增)
运算符优先级(从高到低)
优先级 | 运算符 | 结合性 | ||
---|---|---|---|---|
1 | . () {} ; | 从左到右 | ||
2 | ++ -- ! | 从右到左 | ||
3 | * / % | 从左到右 | ||
4 | + - | 从左到右 | ||
5 | < > <= >= | 从左到右 | ||
6 | == != | 从左到右 | ||
7 | & | 从左到右 | ||
8 | ` | ` | 从左到右 | |
9 | && | 从左到右 | ||
10 | ` | ` | 从左到右 | |
11 | ?: (三元运算符) | 从右到左 |
建议:使用括号明确运算顺序,避免混淆(如 (a + b) * c
)。
2. 控制流语句
用于控制程序执行流程,支持常见的条件和循环结构。
2.1 条件语句
// if-else
int score = 85;
if (score >= 90) {Console.WriteLine("优秀");
} else if (score >= 80) {Console.WriteLine("良好");
} else {Console.WriteLine("一般");
}
// switch(支持模式匹配,C# 7.0+)
var day = DayOfWeek.Monday;
switch (day) {case DayOfWeek.Saturday:case DayOfWeek.Sunday:Console.WriteLine("周末");break;default:Console.WriteLine("工作日");break;
}
// switch表达式(C# 8.0+)
string result = day switch {DayOfWeek.Saturday or DayOfWeek.Sunday => "休息",_ => "工作"
};
2.2 循环语句
// for循环
for (int i = 0; i < 5; i++) {Console.WriteLine(i);
}
// foreach循环(遍历集合)
var names = new List<string> { "Alice", "Bob" };
foreach (var name in names) {Console.WriteLine(name);
}
// while循环
int count = 0;
while (count < 3) {Console.WriteLine(count++);
}
// do-while循环(至少执行一次)
do {Console.WriteLine("执行一次");
} while (false);
3. 方法与参数
方法是代码复用的基本单元,支持多种参数传递方式。
3.1 方法定义与调用
// 方法定义(返回类型、方法名、参数列表)
int Add(int a, int b) {return a + b;
}
// 调用方法
int sum = Add(3, 5); // sum = 8
3.2 参数传递方式
// 值传递(默认)
void Increment(int value) {value++; // 不影响原始值
}
// 引用传递(ref关键字)
void Swap(ref int a, ref int b) {int temp = a;a = b;b = temp;
}
int x = 1, y = 2;
Swap(ref x, ref y); // x=2, y=1
// 输出参数(out关键字)
void SplitName(string fullName, out string firstName, out string lastName) {var parts = fullName.Split(' ');firstName = parts[0];lastName = parts.Length > 1 ? parts[1] : "";
}
SplitName("John Doe", out var first, out var last);
3.3 可选参数与命名参数(C# 4.0+)
// 可选参数(提供默认值)
void PrintInfo(string name, int age = 0) {Console.WriteLine($"Name: {name}, Age: {age}");
}
PrintInfo("Alice"); // Age默认0
// 命名参数(调用时指定参数名)
PrintInfo(age: 30, name: "Bob");
4. 面向对象基础
C# 是纯面向对象语言,支持封装、继承和多态。
4.1 类与对象
// 类定义
class Person {// 字段(通常私有)private string _name;// 属性(封装字段)public string Name {get => _name;set => _name = value;}// 自动属性(简化写法)public int Age { get; set; }// 构造函数public Person(string name, int age) {Name = name;Age = age;}// 方法public void SayHello() {Console.WriteLine($"Hello, I'm {Name}, {Age} years old.");}
}
// 创建对象
var person = new Person("Charlie", 22);
person.SayHello(); // 输出: Hello, I'm Charlie, 22 years old.
4.2 继承与多态
// 基类
class Animal {public virtual void Speak() { // 虚方法,可被子类重写Console.WriteLine("Animal speaks");}
}
// 派生类
class Dog : Animal {public override void Speak() { // 重写基类方法Console.WriteLine("Woof!");}
}
// 多态调用
Animal animal = new Dog();
animal.Speak(); // 输出: Woof!
4.3 接口(Interface)
定义行为契约,类可实现多个接口:
interface ICanSwim {void Swim();
}
interface ICanFly {void Fly();
}
class Duck : ICanSwim, ICanFly {public void Swim() => Console.WriteLine("Swimming...");public void Fly() => Console.WriteLine("Flying...");
}
5. 集合与数组
用于存储和操作多个元素。
5.1 数组(Array)
固定长度,类型统一:
int[] numbers = new int[5]; // 声明长度为5的整数数组
numbers[0] = 100;
// 初始化器语法
string[] names = { "Alice", "Bob", "Charlie" };
// 多维数组
int[,] matrix = new int[3, 3];
5.2 泛型集合(推荐使用)
动态调整大小,类型安全:
// List<T>(动态数组)
var list = new List<int> { 1, 2, 3 };
list.Add(4);
foreach (var num in list) {Console.WriteLine(num);
}
// Dictionary<TKey, TValue>(键值对)
var dict = new Dictionary<string, int> {["apple"] = 1,["banana"] = 2
};
Console.WriteLine(dict["apple"]); // 输出: 1
// H
吗你ashSet<T>(不重复集合)
var uniqueNumbers = new HashSet<int> { 1, 2, 2 }; // 实际只有1, 2
6. 异常处理
使用try-catch-finally
结构捕获和处理运行时错误:
try {int result = 10 / 0; // 抛出DivideByZeroException
}
catch (DivideByZeroException ex) {Console.WriteLine("错误:除数不能为零");Console.WriteLine(ex.Message);
}
catch (Exception ex) {Console.WriteLine("未知错误:" + ex.Message);
}
finally {Console.WriteLine("无论是否出错,都会执行此代码");
}
自定义异常:
public class CustomException : Exception {public CustomException(string message) : base(message) { } }
7. 命名空间与程序集
-
命名空间(Namespace):组织代码,避免命名冲突:
namespace MyApp.Data {public class DatabaseConnection { /* ... */ } } // 使用其他命名空间的类型 using MyApp.Data; var conn = new DatabaseConnection();
-
程序集(Assembly):物理打包单元(.dll 或.exe),包含类型和资源。
8. 现代 C# 语法糖(C# 6.0+)
简化代码编写:
// 字符串内插(C# 6.0+)
string name = "Doubao";
Console.WriteLine($"Hello, {name}!"); // 替代string.Format
// 表达式体方法(C# 6.0+)
public string GetFullName() => $"{FirstName} {LastName}";
// 空条件运算符(C# 6.0+)
string result = person?.Name?.ToUpper(); // 若person或Name为null,直接返回null
// 模式匹配(C# 7.0+)
object obj = 42;
if (obj is int num) { // 类型模式匹配并赋值Console.WriteLine(num);
}
// 元组(Tuple)(C# 7.0+)
(string First, string Last) GetName() => ("John", "Doe");
var (first, last) = GetName();
通过上述内容,你已了解 C# 的基础语法结构。进一步学习可深入高级特性(如 LINQ、异步编程)或框架应用(如ASP.NET Core)。
C# 逻辑练习题解析
1. 判断奇偶数
题目:接收用户输入的整数,判断其奇偶性。 关键逻辑:利用取余运算符 %
判断是否能被 2 整除。
Console.Write("请输入一个整数: ");
int number = Convert.ToInt32(Console.ReadLine()); // 兼容空输入的健壮性处理
string result = number % 2 == 0 ? "偶数" : "奇数";
Console.WriteLine($"{number} 是{result}");
扩展:负数的奇偶性判断与正数一致(如 -3 % 2 = -1
,取余结果符号与被除数相同)。
2. 找出三个数中的最大值
题目:比较三个整数,输出最大值。 解法 1:逐步比较
int a = 10, b = 25, c = 15;
int max = Math.Max(Math.Max(a, b), c); // 利用内置Math类简化代码
Console.WriteLine($"最大值是: {max}");
解法 2:三目运算符
int max = a > b ? (a > c ? a : c) : (b > c ? b : c);
注意:Math.Max
支持多个重载,可直接处理数组或参数列表。
3. 斐波那契数列
题目:输出前 n 项斐波那契数列(0, 1, 1, 2, 3, 5...)。 优化代码:
int n = 10;
int first = 0, second = 1;
Console.Write("斐波那契数列前{0}项: ", n);
for (int i = 0; i < n; i++)
{Console.Write(first + " ");(first, second) = (second, first + second); // 元组赋值简化代码
}
扩展:递归实现(适用于小 n 值,大 n 会因重复计算导致性能问题):
int Fibonacci(int n) => n <= 1 ? n : Fibonacci(n-1) + Fibonacci(n-2);
4. 判断素数
题目:判断输入的正整数是否为素数(只能被 1 和自身整除)。 优化逻辑:
-
1 不是素数,直接排除。
-
只需遍历到平方根(减少循环次数)。
Console.Write("请输入一个正整数: ");
if (!int.TryParse(Console.ReadLine(), out int num) || num < 2) // 输入验证
{Console.WriteLine("输入无效或非素数");return;
}
bool isPrime = true;
for (int i = 2; i <= Math.Sqrt(num); i++)
{if (num % i == 0){isPrime = false;break;}
}
Console.WriteLine($"{num} {(isPrime ? "是" : "不是")}素数");
5. 反转字符串
题目:不使用内置反转方法(如Reverse()
),手动反转字符串。 核心思路:通过字符数组交换首尾字符。
string input = "Hello World";
char[] chars = input.ToCharArray();
for (int i = 0, j = chars.Length - 1; i < j; i++, j--)
{(chars[i], chars[j]) = (chars[j], chars[i]); // 元组交换,无需临时变量
}
Console.WriteLine("反转后的字符串: " + new string(chars));
注意:string
是不可变类型,需转换为char[]
操作。
6. 二分查找
题目:在有序数组中查找目标值的索引。 代码优化:
int[] sortedArray = { 2, 5, 8, 12, 16, 23, 38, 56, 72, 91 };
int target = 23;
int left = 0, right = sortedArray.Length - 1;
while (left <= right)
{int mid = left + (right - left) / 2; // 避免整数溢出if (sortedArray[mid] == target) return mid;else if (sortedArray[mid] < target) left = mid + 1;else right = mid - 1;
}
Console.WriteLine("未找到目标值");
前提:数组必须已排序,否则需先排序(如Array.Sort()
)。
7. 水仙花数
题目:找出 100-999 之间的水仙花数(各位数字立方和等于自身)。 数学拆解:
-
百位:
num / 100
-
十位:
(num / 10) % 10
-
个位:
num % 10
Console.WriteLine("100-999之间的水仙花数:");
for (int i = 100; i <= 999; i++)
{int a = i / 100, b = (i / 10) % 10, c = i % 10;if (a*a*a + b*b*b + c*c*c == i){Console.WriteLine(i); // 常见结果:153, 370, 371, 407}
}
8. 汉诺塔问题
题目:使用递归解决汉诺塔问题,输出移动步骤。 递归逻辑:
-
若只有 1 个盘子,直接移动。
-
否则,先将 n-1 个盘子从起点移到辅助柱,再移动第 n 个盘子,最后将 n-1 个盘子从辅助柱移到终点。
void Hanoi(int n, char from, char to, char aux)
{if (n == 0) return;Hanoi(n-1, from, aux, to); // 递归移动n-1个盘子到辅助柱Console.WriteLine($"将盘子{n}从 {from} 移动到 {to}");Hanoi(n-1, aux, to, from); // 递归移动n-1个盘子到终点
}
Hanoi(3, 'A', 'C', 'B'); // 输出3层汉诺塔的7步移动
扩展:时间复杂度为 O (2ⁿ),n 层需要 2ⁿ-1 步移动。