引言:.NET 库的迷宫
\n\n如果你曾在 Visual Studio 或 Rider 中创建过新项目,你很可能见过两个相似但令人困惑的模板:类库 (.NET Core) 和 类库 (.NET Standard)。一个自然而然的问题就来了:“它们到底有什么区别?我该选哪个,才能避免以后从头重写?”
\n\n这不仅仅是学术上的兴趣。在 Stack Overflow 上,这个问题获得了数千次浏览,而这两种项目类型之间的混淆是初学者最常见的错误之一。在本文中,我们将一劳永逸地弄清楚这个难题,看看 C# 的真实代码示例,并找出哪种库类型最适合你的任务。
\n\n1. 历史简述:从 .NET Framework 到统一时代
\n\n要理解区别,我们需要回顾一下平台的发展历程。以前只有 .NET Framework——一个面向 Windows 的庞大环境。随后出现了 .NET Core——一个跨平台、轻量级的版本。这就产生了一个问题:如何编写一个能在两者上都能运行的库?为此,微软提出了 .NET Standard——一个正式的 API 规范,保证在所有 .NET 实现中都存在。
\n\n然而,随着 .NET 5(以及后续的 .NET 6、7、8)的发布,微软统一了各个平台。现在有了一个统一的基类——.NET(以前的 .NET Core)。这极大地改变了游戏规则。让我们来分析一下这对我们开发者意味着什么。
2. 什么是类库 (.NET Standard)?
\n\n.NET Standard 不是运行时,而是一组约定。可以把它想象成一个“通用适配器”。如果你创建一个以 netstandard2.0 为目标的库,它可以在以下环境中运行:
- \n
- .NET Framework 4.6.1+ \n
- .NET Core 2.0+ \n
- .NET 5/6/7/8 \n
- Xamarin、Mono、Unity 甚至 UWP \n
如果你需要最大程度的平台覆盖,这是理想的选择。你只需编写一次代码,它就能在任何支持该标准版本的平台上运行。
\n\n.NET Standard 库的代码示例
\n\n让我们创建一个以 netstandard2.0 为目标的简单字符串处理库:
// StringHelper.cs\nusing System;\nusing System.Text.RegularExpressions;\n\nnamespace MyStandardLibrary\n{\n public class StringHelper\n {\n /// <summary>\n /// 从字符串中移除所有 HTML 标签。\n /// </summary>\n public static string StripHtmlTags(string input)\n {\n if (string.IsNullOrEmpty(input))\n return string.Empty;\n\n // 一个简单但有效的用于移除标签的正则表达式\n return Regex.Replace(input, "<.*?>", string.Empty);\n }\n\n /// <summary>\n /// 反转字符串。\n /// </summary>\n public static string ReverseString(string input)\n {\n if (string.IsNullOrEmpty(input))\n return string.Empty;\n\n char[] chars = input.ToCharArray();\n Array.Reverse(chars);\n return new string(chars);\n }\n }\n}\n\n请注意:我们只使用了在所有 .NET Standard 2.0 实现中都保证存在的基类(System、System.Text.RegularExpressions)。这个库甚至可以在 .NET Framework 4.6.1 项目上运行——微软虽然已不再积极开发该框架,但它仍在企业领域广泛使用。
3. 什么是类库 (.NET Core / .NET)?
\n\n当你选择 .NET Core 类库(或者如果你使用的是 .NET 5+,则简称为 .NET 类库)时,你就绑定到了平台的一个特定实现。在项目文件 (csproj) 中,你会看到类似 <Target