2

我在 Visual Studio 2010 中创建了一个控制台项目,并选择了 .Net Framework 2.0

namespace ConsoleApp1
{
  class Program
  {
    public int Add(int a, int b = 0, int c = 0)
    {
      Console.WriteLine("a is " + a);
      Console.WriteLine("b is " + b);
      Console.WriteLine("c is " + c);
      return a + b + c;
    }

    public static void Main()
    {
      Program o = new Program();
      Console.WriteLine(o.Add(10));
      Console.WriteLine(o.Add(10, 10));
      Console.WriteLine(o.Add(10, 10, 10));
      Console.WriteLine(o.Add(b: 20, a: 10));
      Console.ReadLine();
    }
  }
}

它成功地工作。

但是,如果我在 Visual Studio 2008 中键入相同的代码,它会失败!

任何人都可以帮我解决这个问题,因为 C#4 附带了命名参数和可选参数?

4

3 回答 3

7

这是因为命名参数是 C# 语言的一项功能,而不是 .net 运行时。

你的 VS2010 使用 C# 4.0 编译器,VS2008 使用 C# 3.0。

这意味着您可以针对较旧的运行时库使用该语言的较新功能。

如果您自己实现 Linq 方法,您甚至可以在 .Net 2.0 和 VS 2010 中使用 Linq(lamda 语法)(请参阅Linq Bridge项目——这篇文章还对它的工作原理进行了更深入的讨论)。

于 2013-05-10T10:33:46.060 回答
3

DaveShaw 解释了命名/可选参数。您还提到(评论)逆变和协变 - 它们是不同的:协变和逆变需要编译更改库更改 -等等。这就是为什么即使使用新编译器,它们也不能在较旧的 .NET 版本上工作。IEnumerable<T>IEnumerable<out T>

所以基本上:

  • 如果您想要的功能完全在编译器中实现,那么只要您使用较新的编译器,它就可能适用于较旧的 .NET 版本
  • 如果您想要的功能需要 BCL 更改,它可能仅适用于更高的 .NET 版本
    • 除非该功能实际上可以完全由其他库实现 - 特别是通过扩展方法。例如,LINQ-to-Objects 可以通过添加LINQBridge在较旧的 .NET 版本(带有较新的 C# 版本)上工作;同样,Microsoft.Bcl.Async向一些 4.5 之前的框架添加类型,允许async/await被使用
于 2013-05-10T10:37:21.377 回答
1

我认为您混淆了 .NET 版本和 C# 版本。如果您使用 Visual Studio 2010 进行编译,则您使用的是 C#4 编译器。这与您引用的 .NET 框架的版本无关。

您使用的功能与编译器版本而不是框架版本相关联,因此您的代码无法在 VS2008 中编译(无论目标框架版本如何,都将在 VS2010 中编译成功)。

于 2013-05-10T10:36:19.457 回答