型の GUID は COM 相互運用に固有のものではなく、すべての .NET 型に GUID があります。Type.GUID プロパティから取得できます。それを生成する CLR のコードは、SSCLI20 ディストリビューションから入手できます。clr/scr/vm/methodtable.cpp、MethodTable::GetGuid() メソッドのコードをチェックアウトすることで、アルゴリズムを見てみることができます。
アルゴリズムの要約:
- 型に [Guid] 属性がある場合は、それを返します
- 型がインターフェイス型の場合、インターフェイス型定義の文字列化されたバージョンを生成します。これは、interoputil.cpp の GetStringizedItfDef() によって行われます。完全修飾型名で始まり、各メンバー定義の文字列バージョンが追加されます。
- 他のすべての型については、クラスの文字列化されたバージョンを生成します。完全修飾型名で始まり、クラス名を追加し、完全修飾アセンブリ名を追加します。
- 結果の文字列は、ヘルパー関数 CorGuidFromNameW() によって Guid にハッシュされます。
これはあなたの質問に答えるのに十分な情報です:
COM Callable Wrapper によって COM インターフェイス ID はどのように生成されますか?
上記のアルゴリズムで生成された Type.GUID を使用します。アルゴリズムのどの要素も、それが実行されるマシンに固有のものではないため、異なるビルド マシンで異なる IID と CLSID を取得することを恐れる必要はありません。
インターフェイスが変更され、新しい IID を生成する必要があるかどうか、CCW はどのように認識しますか?
そうではありません。これは、異なるインターフェイス定義に対して異なる GUID を生成するアルゴリズムに完全に依存しています。
自分で生成してソースファイルで宣言する方が安全でしょうか?
あまり。このアルゴリズムには文書化された障害モードはありません。独自の [Guid] 属性を使用すると、必要なときに変更するのを忘れる可能性が大幅に高まります。これは頻繁に使用されるショートカットであり、DLL Hell の主要なソースです。ハードウェアの例外を診断することはほぼ不可能で、クライアントをクラッシュさせる厄介な種類です。まだ難しいが不可能ではない種類の E_NOINTERFACE とは対照的です。自動生成された Guid に依存することで考えられるデメリットは、実際には 2 つだけです。アセンブリを再構築する前にアセンブリの登録を解除するのを忘れると、開発マシンでレジストリの汚染が発生する傾向があります。また、GUID がすぐにわからないため、COM エラーのトラブルシューティングを行うときに少し遅くなります。確かに、レジストリの汚染は私にとって十分な理由です。