【问题标题】:Is making a parameter non-optional a binary-backwards compatible change?将参数设为非可选是否是二进制向后兼容的更改?
【发布时间】:2014-03-20 20:07:21
【问题描述】:

我正在向函数添加一个新的可选参数,并且我想保持二进制向后兼容性。旧 API 是:

public void Foo(string message, object data = null) { ... }

新的 API 是:

// maintained for backwards compat
public void Foo(string message, object data) { Foo(message, data, null); }

public void Foo(string message, object data = null, TimeSpan? time = null) { ... }

我需要删除旧 API 中数据的默认值的原因是,否则对 Foo("a") 的调用是不明确的。我不想在新方法中要求 data 参数,因为一个常见的用例是做Foo(message, time: time)。同样,我不想继续切换参数顺序,因为我的真实代码中的顺序很有意义。

这个二进制文件是否向后兼容(忽略可能访问 ParameterInfo.DefaultValue 的反射)?我的想法是,由于可选参数是在编译时处理的,所以不传递参数和在 IL 中传递它没有区别。例如下面的 LinqPad 代码:

void Main()
{
    A(0);
    A();
}

// Define other methods and classes here
public int A(int a = 0) { return a; }

为 Main() 生成以下 IL:

IL_0001:  ldarg.0     
IL_0002:  ldc.i4.0    
IL_0003:  call        UserQuery.A
IL_0008:  pop         
IL_0009:  ldarg.0     
IL_000A:  ldc.i4.0    
IL_000B:  call        UserQuery.A

因此,看起来没有区别。但是,我不确定二进制兼容性到底是什么。例如,如果在另一个程序集中定义了 UserQuery.A 的预期签名,编译后的代码是否会保留一些引用?

【问题讨论】:

    标签: c# backwards-compatibility optional-parameters


    【解决方案1】:

    是的;这是向后兼容的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 2011-11-26
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多