Обрыв интерфейса C #, ABI - PullRequest
9 голосов
/ 22 января 2011

Предположим, у нас есть 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?Я знаю, что изменение интерфейсов после их публикации - это плохо, но я действительно хотел бы иметь возможность добавлять свойства в некоторых случаях без добавления подклассов.

Ответы [ 3 ]

10 голосов
/ 22 января 2011

JIT-компилятор разберется со всем этим, а также с источником сообщения об ошибке, если изменение было нарушено.

Однако вы играете в очень опасную игру под названием DLL Hell. Проблема не в том, что они не перекомпилируют свой код, а в том, что они делают . Они будут, в конце концов. Если в этом есть небольшая ошибка, кто-то запустил старую версию вашего установщика, скопировал не тот файл и т. Д., И тогда весь ад провалился. Код не запустится, и у них будет невозможное задание, выясняющее почему. Это произойдет еще долго после того, как вы внесли изменения, у вас не будет возможности угадать, что пошло не так, и вы не сможете им помочь.

Не связывайтесь с этим, поднимите [AssemblyFileVersion] и [AssemblyVersion]. Да, им придется перекомпилировать, когда вы измените последний. Или используйте <bindingRedirect>, что тоже хорошо, теперь есть отслеживаемая запись об этом.

Кстати: это произошло и в .NET Framework. WaitHandle.WaitOne (int) был добавлен в пакет обновления, но без изменения [AssemblyVersion]. Программисты ориентировались на .NET 2.0, но их код не запускался, когда на целевой машине была установлена ​​оригинальная версия 2.0. Очень болезненно.

7 голосов
/ 22 января 2011

Добавление свойств должно быть в порядке.

Один случай, который сломается, если вы, например, добавите что-то в середину автоматически нумерованного перечисления.Например, если у вас есть этот код в вашей библиотеке:

enum Foo
{
   Bar,
   Qux
}

, и вы измените его на это:

enum Foo
{
   Bar,
   Baz,
   Qux
}

Тогда вам также потребуется перекомпилировать любой код, подобный этому:

if (foo == Foo.Qux)
{
    //  ...
}
2 голосов
/ 22 января 2011

Не нарушит совместимость, если используется только сборкой B. Но он сломается, если сборка B определит класс, который реализует интерфейс, потому что этот класс не реализует недавно введенное свойство.

...