C#インターフェイスの破損、ABI
-
16-10-2019 - |
質問
私たちが持っているとします class X
アセンブリのバージョン1 A.dll
:
class X {
SomeType Property { set; get; }
}
そして、アセンブリのバージョン2で A.dll
:
class X {
SomeType Property { set; get; }
SomeType OtherProperty { set; get; }
}
次に、2番目のアセンブリがあるとします B.dll
それは負荷です A.dll
Xを使用します。プロパティが追加されます OtherProperty
ABIを壊しますか?意思 B.dll
使用できません A.dll
/X
?そうでない場合、宣言の順序は何らかの違いをもたらしますか?プロパティが仮想だった場合、違いを生み出しましたか?
私は本当に尋ねていると思います:一般的なABIルールは何ですか?インターフェイスが公開された後にインターフェイスを変更するのは悪いことですが、本当にできるようになりたいと思います。 追加 サブクラスを追加せずに、場合によってはプロパティ。
解決
プロパティの追加は問題ありません。
壊れる1つのケースは、たとえば、自動的に番号の付いた列挙の中央に何かを追加する場合です。たとえば、ライブラリにこのコードがある場合:
enum Foo
{
Bar,
Qux
}
そして、あなたはそれに変えます:
enum Foo
{
Bar,
Baz,
Qux
}
また、次のようなコードを再コンパイルする必要があります。
if (foo == Foo.Qux)
{
// ...
}
他のヒント
JITコンパイラは、変更が破った場合のエラーメッセージのソースであるこれの多くを魅了します。
しかし、あなたはDLL Hellと呼ばれる非常に危険なゲームをプレイしています。問題は、彼らが彼らのコードを再コンパイルしないということではなく、それは彼らが 行う. 。彼らは最終的にそうします。微妙な間違いがある場合、誰かがあなたのインストーラーの古いバージョンを実行し、間違ったファイルなどをコピーしてから、すべての地獄が解放されます。コードは実行されず、 無理だよ 理由を考え出す仕事。これは、変更を加えてからずっと経ちますが、何がうまくいかなかったかを推測する方法はありませんし、それらを助けることができません。
これを混乱させないでください。はい、後者を変更すると再コンパイルする必要があります。または使用します <bindingRedirect>
, 、これも問題ありませんが、今では追跡可能な記録があります。
ところで:これは.NETフレームワークでも起こりました。 watehandle.waitone(int)はサービスパックに追加されましたが、[組み立て]変更はありません。プログラマーは.NET 2.0をターゲットにしましたが、ターゲットマシンが元の2.0をインストールしたときにコードが実行されませんでした。 非常に 痛い。
アセンブリによって使用されている場合、互換性を破ることはありません B
. 。しかし、それはアセンブリの場合に壊れます B
そのクラスは新しく導入されたプロパティを実装していないため、インターフェイスを実装するクラスを定義します。