11

假设我们有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 规则是什么?我知道在发布后更改接口是一件坏事,但我真的希望能够在某些情况下添加属性,而无需添加子类。

4

3 回答 3

11

JIT 编译器会处理掉很多这样的内容,如果更改中断,这也是错误消息的来源。

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

不要乱来,提高 [AssemblyFileVersion] 和 [AssemblyVersion]。是的,当您更改后者时,它们必须重新编译。或者使用<bindingRedirect>,也可以,现在有可追溯记录了。

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

于 2011-01-22T10:42:06.357 回答
7

添加属性应该没问题。

例如,如果您将某些内容添加到自动编号的枚举的中间,将会中断的一种情况。例如,如果您的库中有此代码:

enum Foo
{
   Bar,
   Qux
}

你把它改成这样:

enum Foo
{
   Bar,
   Baz,
   Qux
}

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

if (foo == Foo.Qux)
{
    //  ...
}
于 2011-01-22T08:39:02.447 回答
2

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

于 2011-01-22T10:36:04.510 回答