C#接口破坏,ABI

Jör*_*son 9 .net c# abi binary-compatibility

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

class X {
    SomeType Property { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

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

class X {
    SomeType Property { set; get; }
    SomeType OtherProperty { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Han*_*ant 10

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

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

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

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


Mar*_*ers 7

添加属性应该没问题.

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

enum Foo
{
   Bar,
   Qux
}
Run Code Online (Sandbox Code Playgroud)

并将其更改为:

enum Foo
{
   Bar,
   Baz,
   Qux
}
Run Code Online (Sandbox Code Playgroud)

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

if (foo == Foo.Qux)
{
    //  ...
}
Run Code Online (Sandbox Code Playgroud)