我读了几篇文章说,通过在C#3.0中引入命名参数,参数名称现在是公共合同的一部分。 这是真的吗,它究竟意味着什么?我运行了一个简单的测试并且在MyLib.dll中更改参数名称没有破坏使用带有原始名称的命名参数调用该方法的MyApp.exe ,我认为因为C#编译器在编译时执行了重载解析,并且生成的IL对参数名称一无所知。这就是反汇编代码在Reflector上看到的内容:
private static void Main()
{
bool CS$0$0000 = true;
Class1.DoSomething(CS$0$0000);
Console.ReadKey();
}
...这是原始的源代码:
static void Main() {
MyLib.Class1.DoSomething(a: true);
Console.ReadKey();
}
答案 0 :(得分:19)
我读了几篇文章说,通过在C#3.0中引入命名参数,参数名称现在是公共合同的一部分。这是真的,它究竟意味着什么?
参数名称确实是公共合同的一部分,但该语句包含两个错误。
最明显的错误是命名参数是在C#4.0中引入的,而不是C#3.0。
但更微妙的错误更为重要。在C#4.0中引入命名参数并没有现在使参数名称成为方法的公共契约的一部分。 参数名称总是是公共合同的一部分,因为C#以外的语言具有命名参数功能。特别是,VB始终支持命名参数。
因此,更改库中参数的名称始终是VB重新编译的重大更改。现在它也是C#重新编译的一个重大变化,但这并不意味着它之前是安全的,现在它很危险。这总是危险的。
C#不是唯一的.NET语言,不是目前为止。当您更改某个类型的公开可见表面的一部分时,您可能会破坏每种语言中的程序。拥有或没有功能的C#不会改变这一事实。
答案 1 :(得分:12)
问题是,假设你有一个像这样的公共API:
public void Foo(bool a = false)
{
//....
调用者可以编写一个使用它的应用程序,如下所示:
Foo(a: true);
如果您将方法更改为:
public void Foo(bool aBetterName = false)
{
//....
现在,突然之间,调用者的代码将不再编译,因为编译器(一旦更新到新库)将不再看到名为a
的参数。