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

.NET升级助手为何将部分Reference转为PackageReference?

.NET Upgrade Assistant转换.csproj时Reference的处理逻辑解析

问题说明

使用.NET Upgrade Assistant将旧格式的.NET Framework项目.csproj转换为SDK-style格式时,出现了三种不同的引用处理结果:

  • 部分原<Reference>标签被转换为<PackageReference>
  • 部分<Reference>标签保留原样
  • 还有一部分<Reference>被完全移除

原本认为这些引用都属于.NET Framework,应从本地安装或GAC(全局程序集缓存)引入,疑惑为何会被转为NuGet包引用,且本次示例无C#代码,引用是否被使用不影响转换结果,想了解转换的逻辑依据,以及不同场景下该优先选择NuGet包还是.NET Framework引用。

转换示例

旧格式.csproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{4D2709F3-A2AF-4083-AB04-85BB258F9B2F}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>ConsoleAppOldFormat</RootNamespace>
    <AssemblyName>ConsoleAppOldFormat</AssemblyName>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
    <Reference Include="System.IO" />
    <Reference Include="System.Runtime" />
    <Reference Include="System.ValueTuple" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.ComponentModel.Composition" />
    <Reference Include="System.DirectoryServices" />
    <Reference Include="System.Data.DataSetExtensions" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

转换后的SDK-style .csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <OutputType>Exe</OutputType>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System.IO" />
    <Reference Include="System.Runtime" />
    <Reference Include="System.ValueTuple" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
    <PackageReference Include="System.ComponentModel.Composition" Version="9.0.2" />
    <PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
    <PackageReference Include="System.DirectoryServices" Version="9.0.2" />
  </ItemGroup>
</Project>

转换的逻辑依据

.NET Upgrade Assistant的转换逻辑基于微软对.NET组件的发布策略和SDK-style项目的设计规范:

  • 转为PackageReference的组件:比如Microsoft.CSharp、System.ComponentModel.Composition这类组件,微软已将其作为独立NuGet包发布,这些包同时兼容.NET Framework和现代.NET(如.NET 6/7/8)。使用NuGet引用能更精准地控制版本,避免GAC中版本不一致导致的问题,同时为未来项目升级到跨平台.NET打下基础。
  • 保留为Reference的组件:像System.IO、System.Runtime这类属于.NET Framework的核心基础组件,要么没有对应的独立NuGet包,要么NuGet包是为跨平台场景设计的,但.NET Framework本身已内置完整版本,直接引用本地安装或GAC中的组件更符合.NET Framework项目的运行逻辑。
  • 被移除的组件:比如System、System.Core、System.Data这类是SDK-style项目默认自动引入的.NET Framework核心依赖,SDK会根据<TargetFramework>自动加载这些基础组件,无需显式声明,因此被自动移除。

场景选择建议

优先选择PackageReference的场景

  • 组件有官方发布的NuGet包,且项目未来有升级到跨平台.NET的计划
  • 需要精确控制组件版本,避免团队协作或部署环境中出现GAC版本冲突
  • 依赖的组件在.NET Framework中版本较旧,需要通过NuGet获取更新版本

保留.NET Framework Reference的场景

  • 组件是.NET Framework专属,无官方NuGet包(如某些老旧的系统组件)
  • 项目无需跨平台,且依赖的.NET Framework版本固定,依赖的组件只能从本地安装目录或GAC获取
  • 引用的组件有特殊的系统级依赖,无法通过NuGet包正常运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:18:11