You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何.NET Standard 2.0库发布目录包含大量系统程序集?

为什么.NET Standard 2.0类库发布目录会包含System.Linq等系统程序集?

这个问题其实和.NET Standard的设计以及dotnet publish的默认行为密切相关,我来给你拆解几个核心原因:

1. .NET Standard 2.0的兼容性层特性

.NET Standard 2.0的核心目标是让类库能在多个.NET平台(.NET Framework、.NET Core、Xamarin等)上运行。为了实现跨平台兼容,它引入了兼容性垫片(Facades)——也就是你看到的这些System.*程序集。这些垫片并不是所有目标运行时都原生自带的组件,而是用来填补不同.NET平台之间的API差异:比如有些API在旧版.NET Framework里不存在,垫片就提供了等效实现,确保你的库能在这些平台上正常工作。当你发布.NET Standard类库时,默认会把这些兼容性组件一起打包,因为它无法预知最终会被哪个.NET平台引用,必须保证依赖齐全。

2. NuGet依赖的传递性

你引用的log4net包可能直接或间接依赖了这些系统程序集。当NuGet解析依赖时,如果这些程序集被标记为“需要随库分发”,dotnet publish就会把它们包含到发布目录里。尤其是一些未针对.NET Standard 2.0优化的老版本NuGet包,更容易带来这类不必要的依赖。

3. 类库与应用程序发布逻辑的差异

和.NET Core应用程序不同,类库的发布逻辑是“为所有可能的目标平台准备齐全依赖”。应用程序发布时会根据指定的目标运行时(比如--runtime win-x64)自动裁剪掉运行时自带的程序集,但类库是被其他项目引用的,dotnet publish默认不会做这种裁剪——它要保证无论哪个.NET平台引用这个库,都能找到所有需要的依赖项。

如何减少这些多余的程序集?

如果你明确知道这个类库只会被特定.NET平台(比如.NET Core 2.0)引用,可以试试这些方法:

  • 把类库的目标框架从.NET Standard 2.0改成.NET Core 2.0:这样发布时会自动识别并排除.NET Core运行时原生自带的程序集。
  • 调整项目文件中的依赖配置:对于确定是目标运行时自带的程序集,你可以在项目文件里设置它们的PrivateAssets="all"或者ExcludeAssets="runtime",比如:
    <PackageReference Include="System.Linq" Version="4.3.0">
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    
    注意:这么做之前要确认目标运行时确实包含这些程序集,否则可能导致运行时错误。
  • 更新log4net到最新的.NET Standard兼容版本:新版本的包通常会清理掉不必要的依赖,减少冗余的系统程序集。

内容的提问来源于stack exchange,提问作者Noel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:40:50