C#

技术栈
后端框架
dotnetcsharpmicrosoftobject-orientedasync-awaitlinq

概览

C# 技术栈概览

C#(读作 C Sharp)是微软于 2000 年发布的现代面向对象编程语言,由 Anders Hejlsberg 主导设计。运行在 .NET 平台(原 .NET Framework,现统一为 .NET 6/7/8+)之上,是 .NET 生态的旗舰语言。

解决什么问题

  • Windows 桌面开发:WinForms / WPF 快速构建企业级桌面应用
  • Web 后端开发:ASP.NET Core 构建高性能 REST API 和 MVC 网站
  • 游戏开发:Unity 引擎首选脚本语言
  • 移动开发:Xamarin / MAUI 跨平台移动应用
  • 云服务:Azure 深度集成

关键特性

  • 强类型、面向对象:类、接口、继承、多态、泛型
  • LINQ:语言集成查询,集合操作极为简洁
  • async/await:原生异步编程模型
  • 跨平台:.NET Core 起支持 Windows / Linux / macOS
  • 丰富的生态:NuGet 包管理,微软官方维护,企业级支持
  • 模式匹配、记录类型(C# 9+):函数式编程特性不断增强

安装

C# / .NET 安装指南

1. 环境准备

要求 说明
操作系统 Windows 10+ / macOS 12+ / Linux (Ubuntu 20.04+)
内存 建议 4GB+
磁盘空间 .NET SDK 约 1GB

2. 安装命令

Windows / macOS

dotnet.microsoft.com 下载 .NET SDK 安装程序,双击安装即可。

推荐通过 winget(Windows):

winget install Microsoft.DotNet.SDK.8

macOS (Homebrew)

brew install --cask dotnet-sdk

Linux (Ubuntu/Debian)

wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install -y dotnet-sdk-8.0

验证安装

dotnet --version
# 输出示例: 8.0.100

3. 常见安装问题

问题 解决方案
dotnet 命令找不到 重启终端或手动将安装路径加入 PATH
Linux 上依赖缺失 sudo apt install -y libicu-dev libssl-dev
macOS 安全提示 系统偏好设置 → 安全性与隐私 → 允许
需要特定版本 安装多个 SDK 并存,通过 global.json 指定项目版本
NuGet 还原慢 配置国内镜像:修改 nuget.config,使用 https://api.nuget.org/v3/index.json 或华为/阿里云镜像

示例

C# Hello World — ASP.NET Core Minimal API

目标

用 C# 的 ASP.NET Core Minimal API 创建一个 Web 服务,访问根路径返回 JSON 格式的 "Hello World"。

完整代码

// Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// 根路由 — Hello World
app.MapGet("/", () => Results.Ok(new
{
    message = "Hello World",
    timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
}));

// 健康检查
app.MapGet("/health", () => Results.Ok(new { status = "ok" }));

app.Run();

运行步骤

# 1. 创建项目
dotnet new web -n HelloApi
cd HelloApi

# 2. 将上述代码替换 Program.cs

# 3. 运行
dotnet run

测试

curl http://localhost:5000/
# 输出: {"message":"Hello World","timestamp":1717000000}

curl http://localhost:5000/health
# 输出: {"status":"ok"}

预期输出

$ dotnet run
Building...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000

要点说明

  • WebApplication.CreateBuilder() 创建应用构建器(自动加载配置、DI 容器、日志)
  • MapGet("/", ...) 定义 GET 路由,Lambda 作为处理器
  • Results.Ok() 返回 HTTP 200 + JSON 自动序列化
  • Minimal API 无需 Controller 类,适合微服务和小型 API

C# ASP.NET Core — Controller RESTful API

目标

使用 Controller 模式构建完整的用户管理 RESTful API,模拟数据库 CRUD 操作。

完整代码

// Models/User.cs
public record User(int Id, string Name, string Email);

// Models/CreateUserRequest.cs
public record CreateUserRequest(string Name, string Email);

// Models/UpdateUserRequest.cs
public record UpdateUserRequest(string? Name, string? Email);

// Controllers/UsersController.cs
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private static readonly List<User> _users = new()
    {
        new(1, "Alice", "alice@example.com"),
        new(2, "Bob", "bob@example.com"),
    };
    private static int _nextId = 3;

    // GET /api/users
    [HttpGet]
    public IActionResult GetAll() =>
        Ok(new { total = _users.Count, data = _users });

    // GET /api/users/{id}
    [HttpGet("{id:int}")]
    public IActionResult GetById(int id)
    {
        var user = _users.FirstOrDefault(u => u.Id == id);
        return user is null ? NotFound(new { error = "User not found" }) : Ok(user);
    }

    // POST /api/users
    [HttpPost]
    public IActionResult Create([FromBody] CreateUserRequest request)
    {
        if (string.IsNullOrWhiteSpace(request.Name) ||
            string.IsNullOrWhiteSpace(request.Email))
            return BadRequest(new { error = "name and email are required" });

        var user = new User(_nextId++, request.Name, request.Email);
        _users.Add(user);
        return CreatedAtAction(nameof(GetById), new { id = user.Id }, user);
    }

    // PUT /api/users/{id}
    [HttpPut("{id:int}")]
    public IActionResult Update(int id, [FromBody] UpdateUserRequest request)
    {
        var user = _users.FirstOrDefault(u => u.Id == id);
        if (user is null) return NotFound(new { error = "User not found" });

        var updated = user with
        {
            Name = request.Name ?? user.Name,
            Email = request.Email ?? user.Email
        };
        _users[_users.IndexOf(user)] = updated;
        return Ok(updated);
    }

    // DELETE /api/users/{id}
    [HttpDelete("{id:int}")]
    public IActionResult Delete(int id)
    {
        var user = _users.FirstOrDefault(u => u.Id == id);
        if (user is null) return NotFound(new { error = "User not found" });
        _users.Remove(user);
        return NoContent();
    }
}

Program.cs(注册控制器)

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers(); // 注册控制器
var app = builder.Build();
app.MapControllers();              // 映射控制器路由
app.Run();

测试

curl http://localhost:5000/api/users
curl -X POST http://localhost:5000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Charlie","email":"charlie@example.com"}'
curl -X PUT http://localhost:5000/api/users/1 \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice Updated"}'
curl -X DELETE http://localhost:5000/api/users/3

要点说明

  • [ApiController] 自动模型验证、400 响应、路由推断
  • record 类型提供值相等、with 表达式、不可变性
  • [FromBody] 从 JSON 请求体绑定参数
  • CreatedAtAction 返回 201 + Location 头
  • NoContent() 返回 204(删除成功标准)

C# Hello World 与 LINQ 入门

目标

展示 .NET 8 控制台应用的 Hello World,以及 LINQ 查询、async/await 的基本用法。

完整代码

// Program.cs - .NET 8 顶级语句
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

// 1. Hello World
Console.WriteLine("Hello, .NET 8 World!");

// 2. 记录类型 (C# 9+)
var students = new List<Student>
{
    new("张三", 22, 88.5),
    new("李四", 21, 92.0),
    new("王五", 23, 76.5),
    new("赵六", 22, 95.0),
    new("钱七", 21, 85.0),
};

// 3. LINQ 查询:找出年龄 > 21 且分数 >= 90 的学生
var topStudents = from s in students
                  where s.Age > 21 && s.Score >= 90
                  orderby s.Score descending
                  select new { s.Name, s.Score, Grade = GetGrade(s.Score) };

Console.WriteLine("\n优秀学生:");
foreach (var s in topStudents)
{
    Console.WriteLine($"  {s.Name}: {s.Score}分, 等级: {s.Grade}");
}

// 方法链式写法
var avgScore = students.Where(s => s.Age == 22).Average(s => s.Score);
Console.WriteLine($"\n22岁学生平均分: {avgScore:F1}");

// 4. async/await 异步
Console.WriteLine("\n异步操作演示:");
await FetchDataAsync();

Console.WriteLine("\n按任意键退出...");
Console.ReadKey();

// 辅助方法
static string GetGrade(double score) => score switch
{
    >= 90 => "A",
    >= 80 => "B",
    >= 70 => "C",
    >= 60 => "D",
    _ => "F"
};

static async Task FetchDataAsync()
{
    Console.WriteLine("  开始请求数据...");
    await Task.Delay(1500);  // 模拟异步 I/O
    Console.WriteLine("  数据获取完成!");
}

// 记录类型
record Student(string Name, int Age, double Score);

运行步骤

# 创建项目
dotnet new console -n HelloCSharp
cd HelloCSharp

# 替换 Program.cs 内容后运行
dotnet run

预期输出

Hello, .NET 8 World!

优秀学生:
  赵六: 95分, 等级: A
  张三: 88.5分, 等级: B

22岁学生平均分: 91.8

异步操作演示:
  开始请求数据...
  数据获取完成!

关键点

  • 顶级语句:无需写 Mainclass Program,简洁上手
  • LINQ:两种写法——查询语法(类似 SQL)和方法链
  • 模式匹配switch 表达式优雅处理多条件判断
  • async/await:非阻塞异步,适合 I/O 密集型操作
  • record:不可变数据类,自动生成 Equals/ToString

教程

C# 入门篇:ASP.NET Core Web API 实战

背景

ASP.NET Core 是微软开源的跨平台 Web 框架,在 TechEmpower 基准测试中常年 Top 10。本教程带你构建一个完整的图书管理 Web API。

核心概念

1. 中间件管道

请求依次经过每个中间件,构成管道(Pipeline)。内置中间件:异常处理、静态文件、路由、认证、CORS。

var app = builder.Build();
app.UseExceptionHandler("/error");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

2. 依赖注入(DI)

.NET 内置 IoC 容器。注册服务后,通过构造函数自动注入。

// 注册(Program.cs)
builder.Services.AddScoped<IBookService, BookService>();
builder.Services.AddDbContext<AppDbContext>(...);

// 注入(Controller)
public class BooksController : ControllerBase
{
    private readonly IBookService _service;
    public BooksController(IBookService service) => _service = service;
}

3. 配置系统

支持 appsettings.json、环境变量、命令行参数,自动合并。

// appsettings.json
{
  "ConnectionStrings": {
    "Default": "Data Source=app.db"
  }
}
// 读取
var connStr = builder.Configuration.GetConnectionString("Default");

分步操作

第一步:创建项目

dotnet new webapi -n BookApi
cd BookApi
dotnet add package Microsoft.EntityFrameworkCore.Sqlite

第二步:定义模型与 DbContext

// Models/Book.cs
public class Book
{
    public int Id { get; set; }
    public string Title { get; set; } = "";
    public string Author { get; set; } = "";
    public decimal Price { get; set; }
}

// Data/AppDbContext.cs
public class AppDbContext : DbContext
{
    public DbSet<Book> Books => Set<Book>();
    public AppDbContext(DbContextOptions<AppDbContext> opts) : base(opts) {}
}

第三步:创建 Service 层

public interface IBookService
{
    Task<List<Book>> GetAllAsync();
    Task<Book?> GetByIdAsync(int id);
    Task<Book> CreateAsync(Book book);
    Task<bool> UpdateAsync(int id, Book book);
    Task<bool> DeleteAsync(int id);
}

第四步:编写 Controller

利用 [ApiController] 属性自动处理模型验证错误。

第五步:数据库迁移

dotnet ef migrations add InitialCreate
dotnet ef database update

思考题

  1. AddScopedAddSingletonAddTransient 三种生命周期有什么区别?
  2. 中间件顺序为什么重要?如果 UseAuthentication 放在 UseAuthorization 之后会怎样?
  3. Entity Framework Core 的 AsNoTracking() 什么场景使用?

C# 进阶篇:EF Core、异步编程与性能优化

背景

Entity Framework Core 是 .NET 最流行的 ORM。掌握其高级用法与异步编程模式,是构建高性能 .NET 应用的基础。

核心概念

1. Task-based 异步模式

// ❌ 同步阻塞
public IActionResult GetBooks()
{
    var books = _context.Books.ToList();  // 阻塞线程
    return Ok(books);
}

// ✅ 异步非阻塞
public async Task<IActionResult> GetBooksAsync()
{
    var books = await _context.Books.ToListAsync(); // 释放线程
    return Ok(books);
}

2. EF Core 查询优化

// ❌ N+1 查询 — 每个 Book 的 Author 单独查
var books = await _context.Books.ToListAsync();
foreach (var b in books) Console.WriteLine(b.Author.Name);

// ✅ 预加载 — 一次 JOIN 搞定
var books = await _context.Books
    .Include(b => b.Author)
    .ToListAsync();

// ✅ 投影 — 只查需要的列
var result = await _context.Books
    .Select(b => new { b.Title, AuthorName = b.Author.Name })
    .ToListAsync();

3. 并发处理

// 乐观并发 — 用 RowVersion 检测冲突
public class Book
{
    // ...
    [Timestamp]
    public byte[] RowVersion { get; set; }
}

// 乐观并发异常处理
try
{
    await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
    // 冲突处理:重试 / 合并 / 通知用户
}

4. 原生 SQL 和存储过程

// 参数化查询防注入
var books = await _context.Books
    .FromSqlRaw("SELECT * FROM Books WHERE Price > {0}", minPrice)
    .ToListAsync();

// 存储过程
var result = await _context.Database
    .ExecuteSqlRawAsync("EXEC UpdateBookPrice @id, @price",
        new SqliteParameter("@id", id),
        new SqliteParameter("@price", price));

5. CancellationToken

[HttpGet]
public async Task<IActionResult> GetBooks(CancellationToken ct)
{
    var books = await _context.Books.ToListAsync(ct);
    return Ok(books);
}
// 客户端断开连接时自动取消查询

性能检查清单

优化项 方法
查询性能 投影(Select)、分页、索引、无跟踪查询
内存 AsNoTracking() 只读查询、流式枚举
并发 连接池(AddDbContextPool)、限流中间件
序列化 System.Text.Json 源码生成(AOT)
启动 ReadyToRun、Native AOT 编译

思考题

  1. ConfigureAwait(false) 在 ASP.NET Core 中还需要吗?为什么?
  2. EF Core 的 IQueryableIEnumerable 有什么区别?为什么要把 IQueryable 传给 OData?
  3. Native AOT 有什么限制?哪些场景不适合 AOT 编译?

C# / ASP.NET Core 毕设入门教程

前言

C# 在毕设中的三大主战场:ASP.NET Core Web API 后端WPF/WinForms 桌面应用Unity 游戏开发。本教程聚焦毕设最常用的 ASP.NET Core + EF Core 后端开发。


第一章:快速搭建 Web API 项目

三板斧创建项目

dotnet new webapi -n MyProject
cd MyProject
dotnet run
# 浏览器访问 http://localhost:5000/swagger

项目结构

MyProject/
├── Controllers/       # API 控制器
├── Models/            # 数据模型
├── Services/          # 业务逻辑
├── Data/              # DbContext
├── appsettings.json   # 配置文件
└── Program.cs         # 入口

第二章:构建一个完整的 CRUD API

Model

public class TodoItem
{
    public int Id { get; set; }
    public string Title { get; set; } = "";
    public bool IsCompleted { get; set; }
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

DbContext

public class AppDbContext : DbContext
{
    public DbSet<TodoItem> Todos => Set<TodoItem>();
    public AppDbContext(DbContextOptions<AppDbContext> o) : base(o) {}
}

Controller(最小 API 风格)

app.MapGet("/todos", async (AppDbContext db) => await db.Todos.ToListAsync());

app.MapPost("/todos", async (TodoItem todo, AppDbContext db) =>
{
    db.Todos.Add(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/todos/{todo.Id}", todo);
});

app.MapDelete("/todos/{id}", async (int id, AppDbContext db) =>
{
    var todo = await db.Todos.FindAsync(id);
    if (todo is null) return Results.NotFound();
    db.Todos.Remove(todo);
    await db.SaveChangesAsync();
    return Results.NoContent();
});

第三章:毕设常用模式

三层架构

Controller → Service → Repository → DbContext

JWT 认证(毕设加分项)

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new() {
            ValidateIssuer = true,
            ValidateAudience = true,
            // ... 配置密钥和签发者
        };
    });

全局异常处理

app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        context.Response.StatusCode = 500;
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsync("{\"error\":\"服务器内部错误\"}");
    });
});

第四章:毕设答辩要点

演示流程建议

  1. 启动项目 dotnet run
  2. 打开 Swagger 页面展示 API 列表
  3. 用 Swagger 调几个接口展示 CRUD
  4. 展示数据库中的数据(SQLite 用 DB Browser 打开)

常见答辩问题

  • "为什么选 ASP.NET Core 而不是 Spring Boot?" → 强调 .NET 生态、LINQ 开发效率、学习曲线
  • "数据库用的什么?" → SQLite 零部署,适合毕设
  • "安全性怎么保证?" → JWT 认证、参数校验、CORS 配置

思考题

  1. RESTful API 的设计原则有哪些?你的接口是否符合?
  2. async/await 在 ASP.NET Core 中的作用是什么?
  3. EF Core 的 Include()ThenInclude() 解决了什么问题?

参考资料

  1. [1] Microsoft. C# 语言规范. 2024.
  2. [2] Jeffrey Richter. CLR via C# (4th Edition). 2012.
  3. [3] Andrew Lock. ASP.NET Core in Action (3rd Edition). 2023.
  4. [4] Konrad Kokosa. Pro .NET Memory Management. 2018.
  5. [5] Microsoft. .NET 官方文档. 2024.
  6. [6] Joseph Albahari, Ben Albahari. C# 12 in a Nutshell. 2024.
  7. [7] Andrew Lock. ASP.NET Core in Action, 3rd Edition. 2024.
  8. [8] Microsoft. Entity Framework Core 官方文档. 2024.
  9. [9] Microsoft. C# Language Specification. 2023. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/
  10. [10] Jon Skeet. C# in Depth (4th Edition). 2019.
  11. [11] Andrew Lock. ASP.NET Core in Action (3rd Edition). 2023.
  12. [12] Andrew Troelsen, Phil Japikse. Pro C# 10 with .NET 6. 2022.