繁体   English   中英

更改参数名称而不破坏向后兼容性

[英]Change parameter name without breaking backwards compatibility

我正在研究ac#library,所以我们关注的是打破向后兼容性,但我想知道是否可以更改参数的名称并保持向后兼容性,因为能够使用命名参数? 我想要做的一个例子如下

[Obsolete("use ChangeSpecificFoo(SpecificFoo specificFoo)")]
public void ChangeSpecificFoo(SpecificFoo foo)
{
    _specificFoo = foo;
}

//Compile error ... already defines a member called 'ChangeSpecificFoo' with the same parameter types
public void ChangeSpecificFoo(SpecificFoo specificFoo)
{
    _specificFoo = specificFoo;
}

只是更改参数名称会产生破坏向后兼容性的潜在风险,因为有人可能使用命名参数(如ChangeSpecificFoo(foo: someSpecificFoo)调用方法,但我们不能通过添加具有正确参数名称的新方法来弃用该方法,因为参数名称不包含在方法签名中,因此编译器将其视为重复。

有没有办法解决? 我看到的唯一选择是更改方法名称,因此它不是重复,然后弃用旧方法,或等到我们从参数列表中添加或删除参数并更改参数名称(这可能永远不会发生,因为方法是非常稳定),或者只是进行更改并修复我们在找到它们时使用此库从代码中获得的任何中断。

我对此的第一个倾向很简单: 不要 参数的名称在方法体外部无关紧要。 你认为人们通过名字来呼唤它是正确的,因此可能会破坏它。 但是,仅更改参数名称不会带来任何实际好处。

更改名称的唯一可能原因是重新定义该方法的作用,因为旧名称会导致混淆。 在这种情况下,还应该更改方法的名称,以免引入另一种形式的混淆。 (方法签名相同的事实是不更改参数名称的第一个也是更重要的原因。但是,这可能会解释您可能想要的原因 。)

但是,如果您仍然坚持保持相同的方法签名,但更改名称,则可以执行此操作。 (同样,我强烈建议你要么根本不改变它,要么重命名方法以继续消除混淆。)

解决这个问题的一种方法是使用两个参数的方法,但使第二个可选。 让最后一个参数使用旧名称,然后在方法中分配它。

我还强烈建议记录命名参数的任何使用,以查看您的关注对于将其作为命名参数调用的人是否有效。

public void ChangeSpecificFoo(SpecificFoo specificFoo = null, SpecificFoo foo = null)
{
    if (foo != null && specificFoo == null)
    {
        // Add any other details you can, especially 
        // to figure out who is calling this.
        Log("Someone used a name parameter!!");
    }
    _specificFoo = specificFoo ?? foo;
}

正如Dmitry Bychenko在评论中指出的那样,这不会阻止任何人像这样调用这个方法: ChangeSpecificFoo(null, new SpecificFoo()) ,它将触发日志记录。

他的观察引入了另一个原因,为什么这是一个坏主意:你现在正在引入另一种方式让人们“错误地”调用你的方法。 因此,我将从我的答案的顶部重复我的建议: 要这样做,除非你真的真的需要更改参数名称。

暂无
暂无

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

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