dka*_*man 17 .net c# conditional-compilation .net-4.0
我可以回想一下,在使用MFC时,您可以通过检查_MFC_VER宏来支持多个版本的MFC框架.
我现在正在使用.NET 4做一些事情,并希望在几个地方使用Tuple,但仍然保持其他一切3.5兼容.
我想做的事情如下:
#if DOTNET4
public Tuple<TSource, TResult> SomeMethod<TSource, TResult>(){...}
#else
public KeyValuePair<TSource, TResult> SomeMethod<TSource, TResult>(){...}
#endif
Run Code Online (Sandbox Code Playgroud)
Kev*_*oid 12
如果您使用 .NET Core 构建系统,则可以使用其预定义符号:
#if NET40
public Tuple<TSource, TResult> SomeMethod<TSource, TResult>(){...}
#else
public KeyValuePair<TSource, TResult> SomeMethod<TSource, TResult>(){...}
#endif
Run Code Online (Sandbox Code Playgroud)
预定义符号的列表记录在使用跨平台工具和#if 开发库(C# 参考)中:
.NET 框架:
NETFRAMEWORK,NET48,NET472,NET471,NET47,NET462,NET461,NET46,NET452,NET451,NET45,NET40,NET35,NET20.NET 标准:
NETSTANDARD,NETSTANDARD2_1,NETSTANDARD2_0,NETSTANDARD1_6,NETSTANDARD1_5,NETSTANDARD1_4,NETSTANDARD1_3,NETSTANDARD1_2,NETSTANDARD1_1,NETSTANDARD1_0.NET 5+(和.NET Core):
NET,NET6_0,NET6_0_ANDROID,NET6_0_IOS,NET6_0_MACOS,NET6_0_MACCATALYST, ,NET6_0_TVOS,NET6_0_WINDOWS,NET5_0,NETCOREAPP,NETCOREAPP3_1,NETCOREAPP3_0,NETCOREAPP2_2,NETCOREAPP2_1,NETCOREAPP2_0,NETCOREAPP1_1NETCOREAPP1_0
rmi*_*sen 10
在.csproj(或理论上为.vbproj)中定义自定义编译符号时需要注意一点:它们会覆盖所有先前定义的编译符号.例如,考虑MSBuild片段:
<PropertyGroup Condition="'$(TargetFrameworkVersion)' == 'v4.0'">
<DefineConstants>$(DefineConstants);DOTNET_40</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>ITS_CLOBBERING_TIME</DefineConstants>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
正如其值所示,第二个DefineConstants元素将破坏DefineConstants的第一个值.为避免这种情况,您需要将第二个DefineConstants元素重写为如下所示:
<DefineConstants>$(DefineConstants);ITS_CLOBBERING_TIME</DefineConstants>
Run Code Online (Sandbox Code Playgroud)
此外,您还希望将其放置在所有其他PropertyGroup 之后定义的PropertyGroup中,因为Visual Studio 2010当前在自定义编译符号中添加了这样的方式,如果它们放在Visual之前它将会破坏您定义的任何其他自定义编译符号Studio摒弃了它的定义.我已经向微软提交了这个问题.您可以在Microsoft Connect上跟踪其进度.
您没有可以使用的内置预编译器常量.但是,在VS中创建自己的构建配置很容易,每个配置都有自己的一组定义的常量,当然还有目标框架版本.很多人这样做是为了有条件地编译32或64位差异.
另外,您的条件编译代码会使遇到它的程序员感到沮丧.
编辑,根据评论
编写自己的类可能更好,这样你就可以保证它会做什么,而且你没有任何奇怪的签名或继承问题:
public class Pair<TSource, TResult>
{
public TSource Source { get; set; }
public TResult Result { get; set; }
public Pair() {}
public Pair(TSource source, TResult result)
{
Source = source;
Result = result;
}
// Perhaps override Equals() and GetHashCode() as well
}
Run Code Online (Sandbox Code Playgroud)
与往常一样,使用内置的东西与推出自己的代码进行权衡是很好的.通常这意味着问自己,"我可以维护和支持这些代码吗?" 与"代码是否完成了我需要的东西,开箱即用?"
在这种情况下,由于你不能保证Tuple<T1, T2>,我只是编写你自己的简单的,所以其他开发人员可以轻松呼吸:)
| 归档时间: |
|
| 查看次数: |
7606 次 |
| 最近记录: |