9

我有一个简单的问题:当我在 Visual Studio 2012 中转到 HELP->About 时,窗口显示我正在使用的 .NET 版本是 4.5.50709。但是,当我执行以下代码时:

Console.WriteLine(Environment.Version);

我得到版本 4.0.30319.18034。是什么赋予了?在 Troelsen 的Pro C# 5 & .NET 4.5 Framework中,第 81 页指出 Version 属性返回一个表示 .NET 平台版本的对象。这是不正确的吗?上一个问题的线程表明此属性返回 CLR 版本。如果是这种情况,Version 对象的用途是什么(例如,知道 CLR 版本而不是框架版本有什么用),以及如何实际获取框架版本本身?

4

2 回答 2

17

CLR(公共语言运行时)版本是 4.0.30319.18034。它以 4.0.30319 开头,因为 .NET 4.5 是 .NET 4.0 程序集的就地升级。

4.5 更新完全替换了 .NET 4.0 运行时并将实际版本号设置为 v4.0.30319。

来源 1来源 2

但是您的版本号可能代表带有一些更新的 .NET 4.5,正如用户 Daniel从该列表中推断的那样:

以下是我见过的一些运行时版本示例:

  • 4.0.30319.1 = .NET 4.0 RTM
  • 4.0.30319.269 = 我们在从用户收集的数据中看到的最常见的 .NET 4.0 版本
  • 4.0.30319.544 = 我们的一小部分用户已安装的另一个 .NET 4.0 版本
  • 4.0.30319.17626 = .NET 4.5 RC
  • 4.0.30319.17929 = .NET 4.5 RTM
  • 4.0.30319.18010 = 我的 Windows 8 机器上的当前版本

主要版本号、次要版本号和内部版本号没有改变,所以我认为他们认为 .NET 4.0 和 4.5 之间的差异不会大到足以影响大多数人。预期某些版本 4.0.30319 的 .NET 4.0 应用程序在 .NET 4.5 下仍可按预期工作。


无论您为 .NET 4.0 还是 4.5 编写代码,您都在针对完全相同的 .NET 程序集进行编译。唯一的区别是 .NET 4.5 中的一些新类在针对 .NET 4.0 进行编译时是隐藏的(就好像它们从未存在过一样)。因此,区分 .NET 4.0 和 4.5 的唯一可靠方法似乎是 Christian.K在他的帖子中提出的相当骇人听闻的方法,它不涉及版本号:

该类ReflectionContext在 .NET 框架 4.5 中似乎是全新的,并且可以方便地使用mscorlib. 所以你可以做这样的事情。

public static bool IsNet45OrNewer()
{
    // Class "ReflectionContext" exists from .NET 4.5 onwards.
    return Type.GetType("System.Reflection.ReflectionContext", false) != null;
}
于 2013-04-22T00:22:32.277 回答
2

作为一个练习,我想知道 Visual Studio 如何检索 .NET 版本。您可以查询注册表以查看安装了哪些版本,我想出了以下代码:

static void Main(string[] args)
{
    Console.WriteLine("The following .NET versions are installed:");
    var vers = SearchRegistry(Registry.LocalMachine, "Software\\Microsoft\\NET Framework Setup\\NDP", "Version")
        .GroupBy(v => v)
        .Select(v => (string)v.Key)
        .OrderBy(s => s);

    foreach (string s in vers)
        Console.WriteLine(s);

    Console.WriteLine(string.Format("Newest Installed .NET version: {0}", vers.Last()));
}

private static IEnumerable<object> SearchRegistry(RegistryKey root, string subkey, string search)
{
    foreach (string sub in root.OpenSubKey(subkey).GetSubKeyNames())
    {
        foreach (string val in root.OpenSubKey(subkey).OpenSubKey(sub).GetValueNames())
            if (val == search)
                yield return root.OpenSubKey(subkey).OpenSubKey(sub).GetValue(val);

        foreach (var o in SearchRegistry(root.OpenSubKey(subkey), sub, search))
            yield return o;
    }
}
于 2013-04-22T01:28:16.837 回答