C#:一个被低估的"现代化程度最高的主流语言"

为什么它常被低估

C# 在中文技术圈的存在感长期偏低,原因是它和 Windows、.NET 深度绑定,早年又被视作"Java 的山寨版"。但如果把偏见放一边,只看语言设计本身,2026 年的 C# 可能是主流语言里语法演进最激进、同时工程质量把控最好的那一个。

几个事实:

  • 它是第一个大规模使用"编译期可空引用检查"的主流语言(C# 8,2019 年)。
  • 它比 Java 早十多年支持 async/await(2012 年,Rust 到 2018 才有)。
  • 它的模式匹配、record、init 属性,比同期的 Java 版本早。
  • .NET 从 2016 年 CoreCLR 开始跨平台,现在 Linux 上的部署量不比 Windows 少。

时间线

  • 2000:Anders Hejlsberg 主导(就是后来去做 TypeScript 的那位),最初叫 Cool,后改名 C#。当时的定位是"给 .NET 平台设计的语言"。
  • 2002:.NET Framework 1.0 + C# 1.0,有托管代码、JIT、GC。和 Java 的差别在于它一开始就有值类型(struct)。
  • 2005:C# 2.0 加泛型——注意,这是真正的运行时泛型,不是类型擦除。List<int> 在运行时就是 List<int>,没有装箱。
  • 2012:C# 5 加 async/await。这次影响深远,后面所有语言都在抄这套设计。
  • 2016:.NET Core 发布,跨平台 + 开源。这是分水岭。
  • 2020:C# 8 加可空引用类型、switch 表达式、using 声明。
  • 2022:C# 11 加原始字符串、列表模式、required 成员。
  • 2023-2025:C# 12/13/14 持续加主构造器、集合表达式、params 集合、field 关键字、扩展成员等。

语言特性:真正好用的几块

1. 值类型与引用类型,区分得很清楚

public struct Point { public double X, Y; }        // 栈上/内联,无 GC 压力
public class Node  { public double X, Y; }        // 堆上,引用语义

var p1 = new Point { X = 1, Y = 2 };
var p2 = p1;                                      // 值拷贝,互不影响

var n1 = new Node { X = 1, Y = 2 };
var n2 = n1;                                      // 同一对象

Java 只有基本类型和对象,无法自定义"值语义的结构体";C# 的 struct 能让你在需要高性能的场景(向量、坐标、小记录)避免堆分配。这也是它在游戏(Unity 用它做脚本层)和高性能库上有一席之地的原因。

2. 可空引用类型:把空指针变成编译期问题

#nullable enable

public string? FindName(int id)     // 返回可能为 null,调用方必须处理
{
    return id > 0 ? Lookup(id) : null;
}

var name = FindName(3);
Console.WriteLine(name.Length);     // ⚠️ 编译警告:可能为 null
if (name is not null)
    Console.WriteLine(name.Length); // ✅ 编译器确认已判空

这是现代 C# 最重要的一条工程能力。它不像 TS 那样"类型只是注解",而是在整个代码库里强制区分 string 和 string?,且对现有代码可以不开启(渐进迁移)。配合 not null 约束和 required 成员,能在较大程度上把"空引用异常"这类问题前置。

3. 模式匹配:表达力非常强

public abstract record Shape;
public record Circle(double R) : Shape;
public record Rect(double W, double H) : Shape;

static double Area(Shape s) => s switch
{
    Circle { R: var r }            => Math.PI * r * r,
    Rect   { W: var w, H: var h }  => w * h,
    _ => throw new ArgumentException("unknown shape")
};

配合 record(自动生成相等性、ToString、不可变 init 属性)和 with 表达式,C# 在"数据建模"这块的书写体验比 Java 的 record 更成熟:

var order = new Order { Id = 1, Amount = 199m, Status = OrderStatus.Paid };
var shipped = order with { Status = OrderStatus.Shifted };   // 复制并改一个字段

4. async/await:这套设计的原型

public async Task<string> FetchAsync(HttpClient client, string url)
{
    using var resp = await client.GetAsync(url);
    resp.EnsureSuccessStatusCode();
    return await resp.Content.ReadAsStringAsync();
}

var results = await Task.WhenAll(urls.Select(u => FetchAsync(client, u)));  // 并发

C# 的 async 是编译器生成状态机,不是回调也不是线程。同步与异步的代码看起来完全一样,这是它相比 Go(goroutine + channel)在"写法自然度"上的优势,也是 Rust 生态至今还在为 async 的可用性做斗争的原因。

运行时:.NET 现在是什么

.NET Core 之后,架构清晰:

  • CLR:JIT(RyuJIT)编译 + GC(分代,有 Server GC / Workstation GC 模式)。
  • AOT:Native AOT(2022 后成熟)可以直接编译成本机二进制,启动毫秒级、无需运行时。这让 .NET 终于能进 Serverless 和 CLI 场景。
  • 跨平台:Windows / Linux / macOS,官方 Docker 镜像齐全。
  • 性能:从 .NET 5 开始做了多年专项优化,官方 benchmark 显示在 JSON 序列化、Kestrel HTTP 服务等场景已经和 Go、Node 处于同一梯队,部分指标领先。

一段性能相关的实用配置:

# 容器内跑 Node/Go 类服务时的典型调优
DOTNET_gcServer=1                        # 使用 Server GC,多核吞吐更好
DOTNET_TieredPGO=1                       # 分层编译 + 配置文件引导优化
DOTNET_TC_QuickJitForLoops=1

部署形态:

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -r linux-x64 --self-contained false -o /out

FROM mcr.microsoft.com/dotnet/aspnet:9.0
WORKDIR /app
COPY /out .
ENTRYPOINT ["dotnet", "app.dll"]

生态:强项与弱项

强项:

  • ASP.NET Core:性能一流的 Web 框架,Minimal API 写法和 Go 的 net/http 一样简单。
  • Entity Framework Core:成熟的 ORM,迁移工具完善。
  • Blazor:用 C# 写前端(WebAssembly),适合团队只有 C# 能力的场景。
  • Unity:游戏脚本层事实标准。
  • 桌面:MAUI、WPF(Windows)、Avalonia(跨平台,社区活跃)。
  • 工具链:Visual Studio 的调试、诊断、性能分析体验是第一梯队,dotnet CLI 也够用。

弱项:

  • 机器学习:ML.NET 能用,但和 Python 生态完全不在一个量级。
  • 前端原生的 Web 生态:Blazor 做得不错,但主流仍是 JS/TS。
  • Linux 运维圈的接受度:比 Go 低。很多运维工程师看到 .NET 会先皱眉(这是历史包袱,不是技术问题)。
  • 第三方库数量:NuGet 的规模不如 npm/PyPI,冷门领域容易找不到。

判断标准

选 C#:企业级后端(尤其已有 Windows 系基础设施)、需要强类型 + 良好异步的大型服务、桌面应用、Unity 游戏、团队有 C#/VB 存量、需要 Native AOT 的轻量服务。

不选 C#:纯 Linux 原生云原生栈(Go 更符合生态习惯)、机器学习与数据科学(Python)、对二进制体积极度敏感(Go 的静态单文件更省心)、社区必须完全开源无商业背景的项目。

一个视角

如果你的技术视野只停在"Java、Python、JS、Go",那 C# 会被系统性地忽略。但它其实提供了一个非常完整的对照组:同样是强类型、同样有 GC、同样面向企业,它选择了比 Java 更激进的演进路线。许多后来被 Java、Rust、Kotlin 采用的设计(可空检查、模式匹配、record、async),C# 要么先做,要么做得更彻底。看它一眼,能校准你对"什么才是现代语言"的判断。