使用C#6.0编码但针对.NET 2.0进行编译的缺点。

3
今天我有一个问题想问。C#6.0或其他任何版本都引入了很酷的新功能,使编码更容易。但是假设我的客户运行的是不支持.NET 4.6的WindowsXP系统。如果我使用C#6.0(或以后版本)编写代码,但将其编译为.NET 2.0框架(或其他与发布版本不同的.NET版本),是否存在缺点?
编辑:对于那些不知道如何进行操作的人,您可以通过项目属性->应用程序选项卡->目标框架来指定.NET Framework。而C#语言版本则可通过项目属性->构建选项卡->高级选项->语言版本来指定。
编辑2:在.NET 2.0上编译的C#6.0代码可以运行在WindowsXP上。
static void Main(string[] args)
{
    try
    {
        StringBuilder sb = null;
        string value = sb?.ToString();  // C#6 Feature. Wont throw an exception. 

        if(value == null)
        {
            Console.WriteLine("The Value is null");
        }

        string value2 = sb.ToString();  // Will cause an "Object Reference not set to an instance" exception

    }
    catch ( Exception ex) when (ex.Message.Contains("object")) // C#6.0 conditional catches
    {
        Console.WriteLine("Exception Caught");
    }
    catch(Exception ex)
    {
        Console.WriteLine("Other Exception");
    }

    Console.ReadLine();
}

@Vladimir 不是这样的。许多C# 6.0功能是编译时的,而.Net版本是运行时的。它只影响您可以使用哪些库。 - juharr
@Vladimir 这不是真的。我已经在我的问题中添加了一些 C#6.0 代码,它可以在 .net 2.0 上编译和运行。 - CathalMF
1个回答

6
在使用C#6.0(或者未来最新的C#版本)编写代码时,对于对.NET 2.0框架(或其他与发布的C#版本不同的.NET版本)进行编译,仅会有一些无法使用的功能,包括:
- LINQ,除非你提供自己的实现 - 表达式树 - 扩展方法,除非你添加自己的属性 - FormattableString用于插入字符串(较小,你仍然可以将它作为字符串使用) - 动态类型 - 泛型变量性 - Caller info,除非你添加自己的属性 - Async/await(不确定提供自己的实现有多可行... 是一个相当重要的工作)
其他功能如Lambda表达式、表达式体成员、匿名类型等都应该可以正常工作。

我很好奇,如何使用.NET 2.0创建一个属性来编写扩展方法呢?你能提供一个链接吗? - René Vogt
2
@RenéVogt:基本上,如果您在 System.Runtime.CompilerServices 命名空间中创建自己的 ExtensionAttribute,编译器将使用它。 - Jon Skeet
然而,Windows XP支持.NET 4,这将让您访问上述一些功能。 - Eli Perl
@EliPerl Windows XP只是一个例子。问题实际上是关于针对不同版本的 .net framework 编译代码的。 - CathalMF
谢谢Jon,我不知道这么简单的编译器魔法阻止我们在遗留项目中使用扩展(需要保持在2.0版本)。现在我只是不确定复制linq扩展的源代码是否合法,或者我们是否必须重新实现它们 :) - René Vogt
@RenéVogt:对于LINQ,您可能需要查看LinqBridge:http://www.albahari.com/nutshell/linqbridge.aspx 如果有可能的话,我会尽力更新... .NET 2.0已经很长时间没有得到支持了。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接