我可以在面向 .NET 3.5 SP1 时使用 .NET 4 功能吗?

发布于 2024-11-09 17:02:07 字数 250 浏览 0 评论 0原文

我想使用 .NET 4.0 中的一些功能,但仍以 Visual Studio 2010 中的 .NET 3.5 为目标。基本上我想要这样的东西:

if (.NET 4 installed) then
    execute .NET 4 feature

这是一个可选功能,我希望它在系统具有以下功能时运行:已安装.NET 4.0。如果系统只有 .NET 3.5,则该功能将不会执行,因为它对应用程序来说不是至关重要的。

I would like to use some of the features in .NET 4.0 but still target .NET 3.5 within Visual Studio 2010. Basically I want to have something like:

if (.NET 4 installed) then
    execute .NET 4 feature

This is an optional feature, and I would just like it to run if the system has .NET 4.0 installed. If the system only has .NET 3.5 then the feature would not execute as is it not something that is critical to the application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情绪操控生活 2024-11-16 17:02:08

不可以,因为如果没有 .NET 4 CLR,您就无法使用 .NET 4 功能。问题是程序集在加载时绑定,并且程序集绑定到您为其编译的 CLR 的特定版本。

No, because you can't use .NET 4 features without the .NET 4 CLR. The problem is that assemblies are bound at load time, and the assembly is bound to the specific version fo the CLR you compiled for.

黯然#的苍凉 2024-11-16 17:02:07

首先,您必须以 3.5 版本的框架为目标,但通过使用如下所示的 App.config 使您的程序可由 4.0 框架加载(来自 如何强制应用程序使用 .NET 3.5 或更高版本?):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0"/>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>

至于如何激活4.0功能,取决于您要使用的功能。如果它是内置类上的方法,您只需查找它并使用它(如果存在)。下面是一个 C# 示例(同样适用于 VB):

var textOptions = Type.GetType("System.Windows.Media.TextOptions, " +
        "PresentationFramework, Version=4.0.0.0, " +
        "Culture=neutral, PublicKeyToken=31bf3856ad364e35");
if (textOptions != null)
{
    var setMode = textOptions.GetMethod("SetTextFormattingMode");
    if (setMode != null)
         // don't bother to lookup TextFormattingMode.Display -- we know it's 1
        setMode.Invoke(null, new object[] { this, 1 });
}

如果您将其放入 MainWindow 构造函数中,它将在 .NET 4.0 框架下运行的应用程序中将 TextFormattingMode 设置为 Display,而在 3.5 下不执行任何操作。

如果您想使用 3.5 中不可用的类型,则必须为其创建一个新程序集。例如,使用如下代码创建一个面向 4.0 的名为“Factorial”的类库项目(您必须添加对 System.Numerics 的引用;相同的 C# 免责声明):

using System.Numerics;

namespace Factorial
{
    public class BigFactorial
    {
        public static object Factorial(int arg)
        {
            BigInteger accum = 1;  // BigInteger is in 4.0 only
            while (arg > 0)
                accum *= arg--;
            return accum;
        }
    }
}

然后使用如下代码创建一个面向 3.5 的项目(相同的 C# 免责声明):

using System;
using System.Reflection;

namespace runtime
{
    class Program
    {
        static MethodInfo factorial;

        static Program()
        {   // look for Factorial.dll
            try
            {
                factorial = Assembly.LoadFrom("Factorial.dll")
                           .GetType("Factorial.BigFactorial")
                           .GetMethod("Factorial");
            }
            catch
            { // ignore errors; we just won't get this feature
            }
        }

        static object Factorial(int arg)
        {
            // if the feature is needed and available, use it
            if (arg > 20 && factorial != null)
                return factorial.Invoke(null, new object[] { arg });
            // default to regular behavior
            long accum = 1;
            while (arg > 0)
                accum = checked(accum * arg--);
            return accum;
        }

        static void Main(string[] args)
        {
            try
            {
                for (int i = 0; i < 25; i++)
                    Console.WriteLine(i + ": " + Factorial(i));
            }
            catch (OverflowException)
            {
                if (Environment.Version.Major == 4)
                    Console.WriteLine("Factorial function couldn't be found");
                else
                    Console.WriteLine("You're running " + Environment.Version);
            }
        }
    }
}

如果将 EXE 和 Factorial.DLL 复制到同一目录中并运行它,您将获得 4.0 下的所有前 25 个阶乘,而在 3.5 上仅获得最大 20 的阶乘以及错误消息(或者如果找不到DLL)。

First of all, you have to target the 3.5 version of the framework but make your program loadable by the 4.0 framework by having an App.config that looks like this (from How to force an application to use .NET 3.5 or above?):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0"/>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>

As for how you activate the 4.0 feature, it depends on the feature you want to use. If it's a method on a built-in class, you can just look for it and use it if it exists. Here's an example in C# (it applies equally to VB):

var textOptions = Type.GetType("System.Windows.Media.TextOptions, " +
        "PresentationFramework, Version=4.0.0.0, " +
        "Culture=neutral, PublicKeyToken=31bf3856ad364e35");
if (textOptions != null)
{
    var setMode = textOptions.GetMethod("SetTextFormattingMode");
    if (setMode != null)
         // don't bother to lookup TextFormattingMode.Display -- we know it's 1
        setMode.Invoke(null, new object[] { this, 1 });
}

If you put this in your MainWindow constructor, it will set TextFormattingMode to Display in apps running under the .NET 4.0 framework and do nothing under 3.5.

If you want to use a type that isn't available in 3.5, you have to create a new assembly for it. For example, create a class library project targetting 4.0 called "Factorial" with code like this (you'll have to add a reference to System.Numerics; same C# disclaimer):

using System.Numerics;

namespace Factorial
{
    public class BigFactorial
    {
        public static object Factorial(int arg)
        {
            BigInteger accum = 1;  // BigInteger is in 4.0 only
            while (arg > 0)
                accum *= arg--;
            return accum;
        }
    }
}

Then create a project targetting 3.5 with code like this (same C# disclaimer):

using System;
using System.Reflection;

namespace runtime
{
    class Program
    {
        static MethodInfo factorial;

        static Program()
        {   // look for Factorial.dll
            try
            {
                factorial = Assembly.LoadFrom("Factorial.dll")
                           .GetType("Factorial.BigFactorial")
                           .GetMethod("Factorial");
            }
            catch
            { // ignore errors; we just won't get this feature
            }
        }

        static object Factorial(int arg)
        {
            // if the feature is needed and available, use it
            if (arg > 20 && factorial != null)
                return factorial.Invoke(null, new object[] { arg });
            // default to regular behavior
            long accum = 1;
            while (arg > 0)
                accum = checked(accum * arg--);
            return accum;
        }

        static void Main(string[] args)
        {
            try
            {
                for (int i = 0; i < 25; i++)
                    Console.WriteLine(i + ": " + Factorial(i));
            }
            catch (OverflowException)
            {
                if (Environment.Version.Major == 4)
                    Console.WriteLine("Factorial function couldn't be found");
                else
                    Console.WriteLine("You're running " + Environment.Version);
            }
        }
    }
}

If you copy the EXE and Factorial.DLL into the same directory and run it, you'll get all the first 25 factorials under 4.0 and only the factorials up to 20 along with an error message on 3.5 (or if it can't find the DLL).

橘香 2024-11-16 17:02:07

不,你不能。一种有限的选择是使用条件编译,如下所示:

#if NET40
    some 4.0 code 
#else
    some 3.5 code
#endif

但这样做的限制是它要么编译代码,要么不编译代码 - 您无法在运行时切换执行路径。 (条件编译符号可以在文件顶部声明或者在项目属性构建选项卡中,或者在编译项目时在命令行上(这样它们可以被指定为自动构建的一部分))。

最好的办法就是确保安装了 .Net 4.0 框架 - 完整版本只有 49MB,所以并不大。

No you can't. One limited option is to use conditional compilation, like this:

#if NET40
    some 4.0 code 
#else
    some 3.5 code
#endif

but the limitation of this is that it either compiles the code in or it doesn't - you cannot switch execution path at run time. (The conditional compilation symbols can either be declared at the top of the file or in the project properties build tab, or on the command line when compiling the project (so they can be specified as part of an automated build)).

The absolute best thing to do is ensure the .Net 4.0 framework is installed - it's only 49MB for the full version so it isn't huge.

燕归巢 2024-11-16 17:02:07

这里的主要问题是,您无法在 .NET 4 CLR 上运行为 .NET 3.5 编译的代码,反之亦然。对于.NET4,您需要再次重新编译。

因此,您将有 2 个可执行文件,一个用于 .NET 3.5,第二个用于 .NET 4。两者将具有相同的代码,但您可以使用 预处理器指令,具体来说是 #IF 指令,以区分这两者。

然后您在两个项目的配置中指定特定指令。

Main problem here is, that you can't run code compiled for .NET 3.5 on .NET 4 CLR or vice-versa. You need to recompile again for .NET4.

So you will have 2 executables, one for .NET 3.5 and second for .NET 4. Both will have same code, but you can use Preprocessor Directives, concretly #IF directive, to make differences between those two.

Then you specify specific directive in configuration of both projects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文