简体   繁体   English

C#中的参数名称是否会发生变化?

[英]Is a parameter name change in C# a runtime breaking change?

I read a couple of articles that say that with the introduction of named arguments in C# 3.0, the name of parameters are now part of the public contract. 我读了几篇文章说,通过在C#3.0中引入命名参数,参数名称现在是公共合同的一部分。 Is this true, and what does it mean exactly? 这是真的,它到底意味着什么? I ran a simple test and changing a parameter name in MyLib.dll did not break MyApp.exe which called the method using a named argument with the original name, I think because the C# compiler did overload resolution at compile time, and the generated IL knows nothing about the parameter name. 我运行了一个简单的测试并且在MyLib.dll中更改参数名称没有破坏使用原始名称的命名参数调用该方法的MyApp.exe,我认为因为C#编译器在编译时执行了重载解析,并且生成了IL对参数名称一无所知。 This is what the disassembled code looks on Reflector: 这就是反汇编代码在Reflector上看到的内容:

private static void Main()
{
    bool CS$0$0000 = true;
    Class1.DoSomething(CS$0$0000);
    Console.ReadKey();
}

...and this is the original source code: ......这是原始的源代码:

static void Main() {

    MyLib.Class1.DoSomething(a: true);

    Console.ReadKey();
}

I read a couple of articles that say that with the introduction of named arguments in C# 3.0, the name of parameters are now part of the public contract. 我读了几篇文章说,通过在C#3.0中引入命名参数,参数名称现在是公共合同的一部分。 Is this true, and what does it mean exactly? 这是真的,它到底意味着什么?

It is true that argument names are part of the public contract, but the statement contains two errors. 确实,参数名称是公共合同的一部分,但该语句包含两个错误。

The most obvious error is that named arguments were introduced in C# 4.0, not C# 3.0. 最明显的错误是在C#4.0中引入了命名参数,而不是C#3.0。

But the more subtle error is far more important. 但更微妙的错误更为重要。 The introduction of named arguments in C# 4.0 did not now make names of parameters part of the public contract of a method. 在C#4.0中引入命名参数现在没有使参数名称成为方法的公共契约的一部分。 Names of parameters were always part of the public contract because languages other than C# had the named arguments feature. 参数名称始终是公共合同的一部分,因为C#以外的语言具有命名参数功能。 In particular, VB has always supported named arguments. 特别是,VB始终支持命名参数。

Therefore changing the name of a parameter in a library was always a breaking change for VB recompilation. 因此,更改库中参数的名称始终是VB重新编译的重大变化。 Now it is also a breaking change for C# recompilation, but that doesn't mean that it was safe before and now it is dangerous. 现在它也是C#重新编译的一个重大变化,但这并不意味着它之前是安全的,现在它很危险。 It was always dangerous. 这总是危险的。

C# is not the only .NET language, not by far. C#不是唯一的.NET语言,不是目前为止。 When you change part of the publically visible surface of a type, you risk breaking programs in every language. 当您更改某个类型的公开可见表面的一部分时,您可能会破坏每种语言的程序。 C# having or not having a feature doesn't change that fact. 具有或不具有特征的C#不会改变该事实。

The problem is, say you have a public API like so: 问题是,假设你有一个这样的公共API:

public void Foo(bool a = false)
{
    //....

The caller can write an application that uses it, like so: 调用者可以编写使用它的应用程序,如下所示:

Foo(a: true);

If you then change the method to: 如果您然后将方法更改为:

public void Foo(bool aBetterName = false)
{
    //....

Now, all of a sudden, the caller's code will no longer compile, as the compiler (as soon as they update to your new library) will no longer see a parameter named a . 现在,突然之间,调用者的代码将不再编译,因为编译器(一旦更新到新库)将不再看到名为a的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM