如何正确地使用条件符号来针对多个框架进行目标定位(VS2017)

6

我希望将一个针对 .NET Framework 4.6.1 的库项目迁移到一个新的项目上,该项目同时支持 .NET Framework 4.6.1 和 .NET Standard 2.0。

<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' "> 
    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
</PropertyGroup>

在我目前的代码中,例如我使用:System.Web.Hosting.HostingEnvironment.MapPath() 方法; 所以,我已经在我的.csproj文件中添加了一个条件:

<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
    <Reference Include="System.Web" />
</ItemGroup>

现在在我的代码中,我知道我可以像这样写:

#if NET461
   if (someFolderVar.StartsWith("~/"))
       someFolderVar = System.Web.Hosting.HostingEnvironment.MapPath(someFolderVar);
#endif

我的问题:

如果我将项目更改为针对.NET Framework 4.7,上述代码是否会被执行,还是严格针对.NET Framework 4.6.1?如何判断是否使用4.6.1及以上版本的条件?


为什么不试一下呢? - MakePeaceGreatAgain
1
你不需要支持.NET Framework 4.6.1,因为.NET Standard 2.0已经支持它。https://learn.microsoft.com/en-us/dotnet/standard/net-standard - Feiyu Zhou
关于条件符号,建议参考Serilog:https://github.com/serilog/serilog/blob/dev/src/Serilog/Serilog.csproj - Feiyu Zhou
@FeiyuZhou,.Net Framework 中有一些东西在 NET Standard 中不存在;这意味着有时候两者之间的代码可能会有所不同。 - Learner
对于dotnet库,我认为它们是相同的,因为.NET标准为所有平台定义了公共API。 - Feiyu Zhou
显示剩余4条评论
1个回答

1

看起来我在这篇非常好的文章中找到了一个解决方案。使用NETFULL条件符号(来自文章,但任何名称都可以)应该是一个解决方案:

<PropertyGroup Condition=" '$(TargetFramework)' == 'net461'">
  <DefineConstants>NETFULL</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net47'">
  <DefineConstants>NETFULL</DefineConstants>
</PropertyGroup>

然后是代码:

#if NETFULL
if (someFolderVar.StartsWith("~/"))
   someFolderVar = System.Web.Hosting.HostingEnvironment.MapPath(someFolderVar);
#endif

2
这样做的一个明显问题是,您仍然需要在项目文件中明确提及所有.NET Framework版本。这比在代码中提及它们要好,但对于兼容性仍然存在问题。使用此方法针对.NET 4.7.2会改变行为,而代码中没有任何指示。我觉得很难想象微软没有遇到过这样的问题,这让我觉得这是有意设计的,尽管这种设计的目的我不太清楚。当使用未知的框架时,最好通过错误停止构建并提示“请更新条件”! - Jeroen Mostert
@JeroenMostert 你提出了非常好的观点.. 谢谢,我感激! - Learner
只是一点小提示:你可以给 NETFULL 符号取任何你喜欢的名字,比如 MYCONST。这个常量仅存在于你的程序集中,由 csproj 文件中的 DefineConstants 标签指定。 - MakePeaceGreatAgain
1
顺便说一下,我制作了一个开源的VS2017扩展,具有多目标(SDK / PackageReference)项目模板(4.0、4.5和Standard 2.0),主要基于Learner提到的文章+一些调整,例如在构建后将.nupkg复制到本地路径(目的:更新本地NuGet库)。此外,还有教程(链接在扩展描述中),讨论了您所问的问题。扩展程序:http://marketplace.visualstudio.com/items?itemName=imbVeles.imbACEBasicPack,教程:http://blog.veles.rs/imbace-basicpack-getting-started-draft/ - hardyVeles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接