向公共类添加公共方法是一个重大变化吗?

时间:2018-03-08 10:30:50

标签: c# versioning

例如Person只有一个Age方法:

public class Person
{
    public int Age()
    {
        return 6;
    }
}

添加了Height()方法。

public class Person
{
    public int Age()
    {
        return 6;
    }
    public int Height()
    {
        return 6;
    }
}

这是一个突破性的变化吗?请注意Person未密封。

4 个答案:

答案 0 :(得分:7)

<强> TL;博士;

Eric Lippert再次是对的..

感谢Tim Schmelter对Eric Lippert blog post链接的评论,我改变了原来的答案。

向现有类添加公共方法或属性可能一个重大变化。可能不是,但它可能是!

版本较长

重大更改意味着您正在更改类型的公共API,以便使用当前API的现有代码将无法再编译。

明显的重大变化是删除公共成员,或者改变它们的方式使得使用您的类的代码不再被编译。 这些变化可能是(部分清单!):

  • 向现有方法添加非可选参数。*
  • 将现有方法的参数的数据类型更改为不是原始参数的基本类型的数据类型
  • 将属性的数据类型更改为不是从原始数据类型派生的数据类型
  • 将方法的返回类型更改为不是从原始类型派生的类型

正如Eric所说,即使添加一个新的公共方法,可能一个突破性的变化,就像他在博客中发生的破坏性重载一样,更改类型的属性或参数更具体类型(出自原始​​类型的意思)也可能是一个突破性的变化,原因完全相同。

然而,埃里克还指出,这种情况是如此具体和不太可能,以为假设你不会遇到它们可能是安全的。

  

这种特殊的味道&#34;破坏变化是一个奇怪的变化,因为它几乎可以使一种类型的表面区域的每一个可能的变化成为一个潜在的突破性变化,同时又是一个明显做作和不太可能的场景,没有&#34;现实世界&# 34;开发人员很可能遇到它。

*虽然我们讨论的是破坏更改,但更改可选参数默认值也是一个潜在的突破性更改 - 因为可选参数的工作原理是将默认值作为传递给具有可选参数。更改默认值意味着您必须重新编译使用该方法的所有内容。

答案 1 :(得分:4)

如果任何派生类已经声明了Hight属性并且有#34;将警告视为错误,那将是一个重大改变。打开了。

此更改将生成CS0108 warning(这将成为错误),除非或直到此类的所有者添加new关键字。

答案 2 :(得分:4)

感谢Zohar和Tim的联系;佐哈尔的回答是正确的。如果不完全清楚破坏场景是什么,请考虑:

track_table_id

此程序编译时没有错误,因为重载决议正确地推断出public sealed class Person { public TimeSpan Age { get; set; } } public sealed class Building { public double Height { get; set; } } public sealed class Weird { public static void M(Func<Person, double> f) {} public static void M(Func<Building, double> f) {} public static void N() { M(x => x.Height); } } 必须是x。但是,如果我们将属性Building添加到public double Height {get; set;},则Person包含歧义错误,因为我们无法知道哪个属于Weird.N的类型。

在实践中,这种突破性变化非常罕见,我们在设计语言功能和库时明确决定不认为它很重要。

答案 3 :(得分:2)

要在列表中添加可能的重大更改,这是一个相当令人讨厌的更改:

公司A发布其宏伟的新班级Foo。 B公司喜欢新的东西,但是错过了它决定通过完全根据他们的需求定制的扩展方法实现的一些功能:

namespace A {
     public class Foo { ... } }

namespace B {
     static class Extensions {
         public static string Frob(this Foo foo) { .... } } }

公司A意识到它可以做得更好,并决定使用一些新功能升级Foo,并决定添加一个具有通用实现的新方法string Frob()

公司A发布更新的库,公司B愉快地使用新版本更新其软件。一切都很好......但是一个突然的变化发生了同样的事情; foo.Frob()现已解析为Foo.Frob(),而不是扩展方法Extensions.Frob(this Foo foo)