C#接口破坏,ABI

假设我们在程序集A.dll版本1中有class X

 class X { SomeType Property { set; get; } } 

然后在程序集A.dll第2版​​中:

 class X { SomeType Property { set; get; } SomeType OtherProperty { set; get; } } 

现在假设我们有第二个程序集B.dll加载A.dll并使用X.添加属性OtherProperty打破ABI吗? B.dll会不会使用A.dll / X ? 如果没有,声明的顺序会有什么不同吗? 如果属性是虚拟的,它有什么不同吗?

我想我真的在问:ABI的一般规则是什么? 我知道在发布之后更改接口是一件坏事,但我真的希望能够在某些情况下添加属性,而无需添加子类。

添加属性应该没问题。

例如,如果您在自动编号的枚举的中间添加一些内容,则会破坏一个案例。 例如,如果您的库中有此代码:

 enum Foo { Bar, Qux } 

并将其更改为:

 enum Foo { Bar, Baz, Qux } 

然后你还需要重新编译这样的代码:

 if (foo == Foo.Qux) { // ... } 

JIT编译器会对此进行大量处理,如果更改中断,也会出现错误消息的来源。

然而,你正在玩一个名为DLL Hell的非常危险的游戏。 问题不在于它们不会重新编译代码,而是在它们执行时 。 他们最终会。 如果那时有一个微妙的错误,有人运行了旧版本的安装程序,复制了错误的文件,等等,然后一切都崩溃了。 代码将无法运行,他们将找到一个不可能的工作找出原因。 这种情况会在你做出改变很久之后发生,你也无法猜出出了什么问题,也无法帮助他们。

不要搞乱这个,提高[AssemblyFileVersion]和[AssemblyVersion]。 是的,当你改变后者时,他们将不得不重新编译。 或者使用 ,这也很好,现在有一个可追踪的记录。

顺便说一下:这也发生在.NET Framework中。 WaitHandle.WaitOne(int)已添加到Service Pack中,但没有[AssemblyVersion]更改。 程序员针对.NET 2.0,但是当目标机器安装了原始2.0时,它们的代码将无法运行。 非常痛苦。

如果仅由程序集B使用它,它将不会破坏兼容性。 但是如果程序集B定义了一个实现接口的类,它将会中断,因为该类没有实现新引入的属性。