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

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

然后在程序集的版本 2 中 A.dll:

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]。是的,当您更改后一个时,它们必须重新编译。或者使用 <bindingRedirect>, ,这也很好,现在有可追溯的记录了。

顺便提一句:这也发生在 .NET Framework 中。WaitHandle.WaitOne(int) 已添加到服务包中,但没有 [AssemblyVersion] 更改。程序员以 .NET 2.0 为目标,但当目标计算机安装了原始 2.0 时,他们的代码将无法运行。 非常 痛苦。

如果仅由组件使用,它不会打破兼容性 B. 。但是如果组件会破裂 B 定义一个实现接口的类,因为该类未实现新引入的属性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top