.NET Core class 库的条件编译符号
Conditional compilation symbol for a .NET Core class library
我创建了一个 .NET Core R2 class 库,并且有一些用于多个不同平台的通用代码。
部分代码在 .NET Core 平台中无效,因此我希望将其包装在 条件编译符号 周围。我首先在互联网上搜索,看看是否可以找到一个内置符号(例如 Silverlight 应用程序的 SILVERLIGHT 和 Windows 8 个应用程序的 WINFX_CORE),但我找不到任何信息,所以我决定创建自己的符号。这似乎也行不通。
从我阅读的所有内容来看,添加和使用符号应该很容易。只需在项目属性 → Build 选项卡中为条件编译符号添加一个值。我这样做了,但它似乎不起作用。这是一些屏幕截图...
请注意,我在条件编译符号中添加了一个 NET_CORE
值,但是当我在代码中使用它时,代码并没有被忽略。
.NET Core平台有内置符号吗(我用的是R2)?
如果没有,我在创建自己的符号时做错了什么?
.xproj 文件:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>253184d7-9b42-4233-a871-8cfa3ee9e83e</ProjectGuid>
<RootNamespace>Linq2Db.NetCore</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
更新: 我能够使用提供的答案中的 link 解决此问题。这是详细信息...
最初 project.json
文件看起来像这样...
{
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
},
"frameworks": {
"netstandard1.5": {
"imports": "dnxcore50"
}
},
"buildOptions": {
"defines": [ "NET_CORE" ]
}
}
我把它改成这个解决了这个问题...
{
"frameworks": {
"netstandard1.5": {
"imports": "dnxcore50",
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
},
"buildOptions": {
"define": [ "NET_CORE" ]
}
}
}
}
条件变量应该在您的 project.json RC2 文件中定义,我这里有一个示例项目,
Port #SNMP from .NET Core RC1 to RC2
但也有本文中预定义的,
.NET Core xproj 项目类型中存在错误。当你通过项目设置定义一个条件编译符号时,它将元素定义为"defines",但这是不正确的。它应该创建一个名为 "define" 的元素。您可以通过手动编辑 project.json 来解决此问题。
我已经在微软的两个地方记录了这个错误。请花点时间向 Microsoft 表达你的不满,以便他们最终能够解决它,而不是给其他人带来这种痛苦。
本帖对问题进行了详细说明,包括重现步骤和截图:
https://github.com/dotnet/cli/issues/4022#issuecomment-238777946
这是 Microsoft Connect 错误报告:
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/2983351/conditional-compilation-symbols-broken-in-net-core-projects#tabs
由于 xproj 已停产,以下是在新的 Visual Studio 2017 .csproj 文件中的完成方式。
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' Or '$(TargetFramework)' == 'netstandard1.6' ">
<DefineConstants>NET_CORE</DefineConstants>
</PropertyGroup>
然后代替:
private TypeInfo GetTypeInfo(Type type)
{
#if NETSTANDARD1_3 || NETSTANDARD1_6
// Core
#else
// Full framework
#endif
}
你可以这样做:
private TypeInfo GetTypeInfo(Type type)
{
#if NET_CORE
// Core
#else
// Fullframework
#endif
}
有关多目标的更多详细信息,请参阅此处:Developing Libraries with Cross Platform Tools, How to Multitarget
我创建了一个 .NET Core R2 class 库,并且有一些用于多个不同平台的通用代码。
部分代码在 .NET Core 平台中无效,因此我希望将其包装在 条件编译符号 周围。我首先在互联网上搜索,看看是否可以找到一个内置符号(例如 Silverlight 应用程序的 SILVERLIGHT 和 Windows 8 个应用程序的 WINFX_CORE),但我找不到任何信息,所以我决定创建自己的符号。这似乎也行不通。
从我阅读的所有内容来看,添加和使用符号应该很容易。只需在项目属性 → Build 选项卡中为条件编译符号添加一个值。我这样做了,但它似乎不起作用。这是一些屏幕截图...
请注意,我在条件编译符号中添加了一个 NET_CORE
值,但是当我在代码中使用它时,代码并没有被忽略。
.NET Core平台有内置符号吗(我用的是R2)?
如果没有,我在创建自己的符号时做错了什么?
.xproj 文件:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>253184d7-9b42-4233-a871-8cfa3ee9e83e</ProjectGuid>
<RootNamespace>Linq2Db.NetCore</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
更新: 我能够使用提供的答案中的 link 解决此问题。这是详细信息...
最初 project.json
文件看起来像这样...
{
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
},
"frameworks": {
"netstandard1.5": {
"imports": "dnxcore50"
}
},
"buildOptions": {
"defines": [ "NET_CORE" ]
}
}
我把它改成这个解决了这个问题...
{
"frameworks": {
"netstandard1.5": {
"imports": "dnxcore50",
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
},
"buildOptions": {
"define": [ "NET_CORE" ]
}
}
}
}
条件变量应该在您的 project.json RC2 文件中定义,我这里有一个示例项目,
Port #SNMP from .NET Core RC1 to RC2
但也有本文中预定义的,
.NET Core xproj 项目类型中存在错误。当你通过项目设置定义一个条件编译符号时,它将元素定义为"defines",但这是不正确的。它应该创建一个名为 "define" 的元素。您可以通过手动编辑 project.json 来解决此问题。
我已经在微软的两个地方记录了这个错误。请花点时间向 Microsoft 表达你的不满,以便他们最终能够解决它,而不是给其他人带来这种痛苦。
本帖对问题进行了详细说明,包括重现步骤和截图: https://github.com/dotnet/cli/issues/4022#issuecomment-238777946
这是 Microsoft Connect 错误报告: https://connect.microsoft.com/VisualStudio/feedbackdetail/view/2983351/conditional-compilation-symbols-broken-in-net-core-projects#tabs
由于 xproj 已停产,以下是在新的 Visual Studio 2017 .csproj 文件中的完成方式。
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' Or '$(TargetFramework)' == 'netstandard1.6' ">
<DefineConstants>NET_CORE</DefineConstants>
</PropertyGroup>
然后代替:
private TypeInfo GetTypeInfo(Type type)
{
#if NETSTANDARD1_3 || NETSTANDARD1_6
// Core
#else
// Full framework
#endif
}
你可以这样做:
private TypeInfo GetTypeInfo(Type type)
{
#if NET_CORE
// Core
#else
// Fullframework
#endif
}
有关多目标的更多详细信息,请参阅此处:Developing Libraries with Cross Platform Tools, How to Multitarget