假设我们在程序集class X
的版本1中有A.dll
:
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的一般规则是什么?我知道在发布后更改接口是一件坏事,但我真的希望能够在某些情况下添加属性,而无需添加子类。
答案 0 :(得分:10)
JIT编译器会对此进行大量处理,如果更改中断,也会出现错误消息的来源。
然而,你正在玩一款名为DLL Hell的非常危险的游戏。问题不是他们不重新编译他们的代码,而是他们做时。他们最终会。如果那时有一个微妙的错误,有人运行了旧版本的安装程序,复制了错误的文件,等等,然后所有地狱都松了一口气。代码将无法运行,他们将有不可能的工作找出原因。这种情况会在你做出改变后很久就会发生,你也无法猜出出了什么问题,也无法帮助他们。
不要搞砸这个,提高[AssemblyFileVersion]和[AssemblyVersion]。是的,当你改变后者时,他们将不得不重新编译。或者使用<bindingRedirect>
,这也很好,现在有一个可追溯的记录。
顺便说一句:这也发生在.NET Framework中。 WaitHandle.WaitOne(int)已添加到Service Pack中,但没有[AssemblyVersion]更改。程序员针对.NET 2.0,但是当目标机器安装了原始2.0时,它们的代码将无法运行。 非常痛苦。
答案 1 :(得分:6)
添加属性应该没问题。
例如,如果您在自动编号的枚举的中间添加某些内容,则会破坏一个案例。例如,如果您的库中有此代码:
enum Foo
{
Bar,
Qux
}
然后将其更改为:
enum Foo
{
Bar,
Baz,
Qux
}
然后你还需要重新编译这样的代码:
if (foo == Foo.Qux)
{
// ...
}
答案 2 :(得分:2)
如果仅由程序集B
使用,它不会破坏兼容性。但是如果程序集B
定义了一个实现接口的类,它将会中断,因为该类没有实现新引入的属性。