我正在为函数添加一个新的可选参数,我想保持二进制向后兼容性。旧的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的预期签名进行一些引用?
答案 0 :(得分:2)
是;这是向后兼容的。