Чтобы немного расширить ответ Джареда (полностью правильный):
В мире COM каждый интерфейс идентифицируется глобально уникальным идентификатором. Нет такой вещи как «изменение» интерфейса в COM; интерфейсы должны быть одинаковыми всегда. Вместо этого вы создаете новый интерфейс и назначаете ему новый GUID. Любые два интерфейса, которые отличаются, должны иметь разные GUID. Равенство интерфейса определено как равенство GUID в COM.
В мире .NET равенство типов сложнее. Тип связан с определенной сборкой, с одной стороны. Но не только это! Если вы загрузите одну и ту же сборку дважды (скажем, один раз по ее имени сборки и один раз по расположению на диске) и запросите две сборки для «одного и того же» типа, вы получите два объекта типа разных , и они не сравнивать как равные, хотя очевидно, что они имеют одинаковый GUID.
Очевидно, что это главная отправная точка; .NET и COM глубоко несовместимы в этом отношении. Что происходит, когда должно произойти взаимодействие? Каким-то образом COM и .NET должны договориться о некоторых правилах сравнения типов на равенство, когда оба используются в одном и том же процессе. (Потому что .NET вызывает код COM или наоборот.)
Таким образом, в .NET вы можете сказать: «этот тип связан с этим GUID». Когда применяются правила COM, код COM сравнивает два типа на равенство путем сравнения идентификаторов GUID, потому что именно это означает равенство в мире COM.
В .NET типы сравниваются на равенство с использованием обычных правил .NET.
Это представляет значительную потенциальную проблему в обычном сценарии. Предположим, вы написали программу .NET, которая взаимодействует с большой и сложной библиотекой COM. Просто чтобы выбрать совершенно неслучайный пример, предположим, что вы написали управляемое расширение для Word, которое имеет абсолютно огромную «поверхность» COM. Эта поверхность открывается для мира .NET через Первичную сборку взаимодействия, которая содержит «фиктивные» типы, которые имеют все те же GUID, что и соответствующие интерфейсы в мире COM. Затем можно написать код .NET для взаимодействия с уровнем COM через «фиктивные» объекты, которые выглядят как объекты COM соответствующего типа интерфейса, а код .NET - объектами соответствующего типа .NET.
Так что это прекрасно работает. А затем вы отправляете свою библиотеку .NET клиентам и понимаете, что Word не отправляет PIA клиентам автоматически . Скорее, вы обязаны отправить свою PIA. Что огромно.
Так родилась функция «без PIA» в C # 4. В C # 4 вы можете генерировать расширение Word, которое делает внутреннюю копию только части слова PIA, которое оно фактически использует . Который обычно намного меньше. Затем вы можете перераспределить вашу библиотеку расширений без перераспределения большой PIA.
Но это сразу же создает проблему. Предположим, что есть две таких библиотек, и они хотят взаимодействовать друг с другом , используя типы интерфейсов, которые являются общими для обоих, в PIA ? С точки зрения .NET типы создаются для каждой сборки; копии типов PIA в каждой библиотеке одинаковы с точки зрения COM, но отличаются с точки зрения .NET.
Поэтому мы добавили специальную функцию в CLR v4. В этой ситуации два типа в двух разных сборках (и тип PIA, если он есть!) унифицированы CLR и обрабатываются как равные GUID, совпадая поведение COM.
Детали, конечно, намного сложнее, чем этот простой набросок. Я просто хочу сказать, что вы открываете здесь огромную банку с червями; как GUID взаимодействуют с равенством типов - это глубокая и сложная тема, которую мало кто понимает полностью.