代码之家  ›  专栏  ›  技术社区  ›  dkackman Srinivas Kokkula

是否可以有条件地编译到.NET框架版本?

  •  16
  • dkackman Srinivas Kokkula  · 技术社区  · 15 年前

    我可以回忆起在使用MFC时,您可以通过检查 _MFC_VER 宏。

    我现在正在用.NET4做一些事情,我想在几个地方使用tuple,但仍然保持其他3.5的兼容性。

    我要做的事情是:

    #if DOTNET4
        public Tuple<TSource, TResult> SomeMethod<TSource, TResult>(){...}
    #else
        public KeyValuePair<TSource, TResult> SomeMethod<TSource, TResult>(){...}
    #endif
    
    4 回复  |  直到 9 年前
        1
  •  7
  •   Brian Gideon    15 年前

    没有可以使用的内置预编译器常量。但是,很容易在vs中创建自己的构建配置,每个配置都有自己的一组定义常量,当然还有一个目标框架版本。很多人这样做是为了有条件地编译基于32或64位的差异。

        2
  •  10
  •   rmiesen winebarrel    14 年前

    在.csproj(或.vbproj,理论上)中定义自定义编译符号时需要注意的一个大警告是:它们会覆盖以前定义的所有编译符号。例如,考虑msbuild代码段:

      <PropertyGroup Condition="'$(TargetFrameworkVersion)' == 'v4.0'">
        <DefineConstants>$(DefineConstants);DOTNET_40</DefineConstants>
      </PropertyGroup>
      <PropertyGroup>
        <DefineConstants>ITS_CLOBBERING_TIME</DefineConstants>
      </PropertyGroup>
    

    如其值所示,第二个defineconstants元素将删除defineconstants的第一个值。为了避免这种情况,您需要重写第二个defineconstants元素,使其看起来像这样:

        <DefineConstants>$(DefineConstants);ITS_CLOBBERING_TIME</DefineConstants>
    

    此外,您还需要将其放入定义的属性组中。 之后 所有其他属性组(如Visual Studio 2010当前添加的自定义编译符号)都将以这样的方式删除您定义的任何其他自定义编译符号(如果这些符号放在Visual Studio下拉其定义之前)。我已将此问题提交给Microsoft。您可以在以下位置跟踪其进度: Microsoft Connect .

        3
  •  7
  •   Doug    9 年前

    附带说明的是,条件编译代码会让遇到它的程序员感到沮丧。

    根据评论编辑

    最好是编写自己的类,这样您就可以保证它将要做什么,并且您没有任何奇怪的签名或继承问题:

    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
    }
    

    和往常一样,使用内置的东西和使用自己的代码相比,这是很好的权衡。一般来说,这意味着问问自己,“我可以维护和支持这段代码吗?”vs.“代码能做我需要的事情吗,开箱即用?”

    在这种情况下,因为你不能保证 Tuple<T1, T2> ,我只写你自己的一个简单的,这样其他开发人员就可以轻松地呼吸了:)

        4
  •  1
  •   Mr.O    10 年前

    因为您应该有不同的项目,所以您可以有分部类,并且只引用每个项目所需的具有特定逻辑的类:

    类名 公共部分类名…}

    40.CS 公共部分类名{ 公共tuple somemethod()… }

    35.CS 公共部分类名{ public keyValuePair someMethod()… }