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

Dol*_*lev 2 c# versioning

例如Person,只有一种Age方法:

public class Person
{
    public int Age()
    {
        return 6;
    }
}
Run Code Online (Sandbox Code Playgroud)

Height()添加了一种方法.

public class Person
{
    public int Age()
    {
        return 6;
    }
    public int Height()
    {
        return 6;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个突破性的变化吗?注意Person不要密封.

Zoh*_*led 7

TL;博士;

Eric Lippert再次是对的..

感谢Tim Schmelter对Eric Lippert 博客文章链接的评论,我改变了原来的答案.

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

版本较长

突破性更改意味着您正在更改类型的公共API,使得使用当前API的现有代码将无法再编译.

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

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

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

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

这种破坏变化的特殊"味道"是一个奇怪的现象,因为它几乎可以使一种类型的表面区域的每一种可能的变化成为潜在的破坏性变化,同时又是如此明显的人为和不太可能的情况世界"开发商可能会遇到它.


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


Dam*_*ver 5

如果任何派生类已经声明了Hight属性并启用了“错误警告处理”,那将是一个重大突破。

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


Eri*_*ert 5

感谢Zohar和Tim的联系;佐哈尔的答案是正确的。如果尚不清楚中断情况是什么,请考虑:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

该程序编译没有错误,因为重载分辨率正确推断出x必须为Building。但是,如果将属性添加public double Height {get; set;}Person,则会Weird.N包含歧义错误,因为我们无法知道哪个类型是x

实际上,这种突破性的变化非常罕见,以至于我们在设计语言功能和库时明确决定不将其视为重要。