共用方式為


繼承、彙總和內含項目

COM 在 .NET Framework 中的重複使用性是透過繼承 (Inheritance) 達成的。 COM 型別可以參與繼承做為基底類別。 在下列情況請使用繼承、彙總 (Aggregation) 或內含項目模型:

模型

使用於

繼承

將 Managed 物件公開為外部物件

彙總

讓外部物件能公開其他物件的介面實作而不需修改

內含項目

讓外部物件能修改內部物件的行為

繼承

當 Managed 介面公開 (Expose) 給 COM 時,永遠會擴充 IUnknownIDispatch,即使該介面是從 Managed 方面其他介面所繼承而來也一樣。 同樣的規則也適用於對 Managed 類別產生的類別介面

.NET Framework 藉由加入實作繼承擴充了 COM 模型的重複使用性。 Managed 型別可以直接或間接從 COM Coclass 衍生;更明確地說,它們可以從執行階段產生的執行階段可呼叫包裝函式衍生。 衍生型別 (Derived Type) 可以公開 COM 物件的所有方法和屬性,以及在 Managed 程式碼中實作的方法和屬性。 所產生的物件部分是在 Managed 程式碼中實作,一部分是在 Unmanaged 程式碼中實作。

若要符合做為基底類別的資格,Coclass 必須:

Managed 型別可以對合格的 Coclass 擴充 RCW,並覆寫基底物件所提供的方法。 如果您要覆寫任何方法,必須覆寫介面的所有基底方法。

Managed 型別會以它從 Managed 基底物件繼承的同樣方式從 RCW 繼承。 在以下程式碼範例中,Managed Catapult 類別是從 COM 型別 AcmeLib.Slingshot 衍生。

#using "AcmeLib.dll"    // Provides definition of Slingshot.

__gc class Catapult : public AcmeLib.Slingshot  // Extends the COM type.
{
    // Delegates to base implementation.
    Load() { //… };  
   
    Fire()               
    {
        // Engages in some behavior before delegating to the base 
        // implementation.
        Slingshot::Fire();
    }

    // The Aim method needs to be overridden.
    Aim() { //… }         
}
Catapult *cp = new Catapult();

// Calls derived implementation.
cp->Load();
// Calls base implementation.
cp->Aim();
// Calls derived which delegates to base.
cp->Fire();

彙總

若要讓某一個 COM 類別公開介面的方式,像是實作於第二個 COM 類別上,那麼這第二個類別會彙總第一個類別。 COM 物件可以彙總 .NET 物件,在這種情況下,所有這個物件的介面 (包括它的類別介面) 都是透過外部物件使用。 內部 .NET 物件會將對其 IUnknown 方法的呼叫委派給控制的 IUnknown

彙總比內含項目(在下一節中描述) 要稍微複雜一些。 您通常會用它來讓外部物件能夠公開另一個物件的介面實作,而不需修改。 所有 Managed 物件都會以做為內部物件使用的 Managed 物件,自動支援 COM 樣式的彙總。 為了彙總 (Aggregate) Managed 物件,Unmanaged 外部物件會呼叫 CoCreateInstance 以建立 Managed 內部物件,然後將外部物件的 IUnknown 做為 OuterUnknown 參數傳遞。 當外部 IUnknown 在建構期間傳遞給 Managed 物件時,Managed 物件會快取這個介面並以下述方式使用它:

  • 外部物件掌控內部 IUnknown 的不可委派 (Nondelegating) IUnknown。 不可委派的 IUnknown 行為與一般的 IUnknown 行為一樣;也就是說,如果物件實作介面,它便會成功,反之,則會失敗。 不可委派的 IUnknown 不會將呼叫轉送給外部物件。

  • 如果內部物件被查詢了一個它不支援的介面,內部物件會將這個呼叫委派給外部物件的 IUnknown 介面。

  • 所有對內部物件的 QueryInterfaceAddRefRelease 方法的呼叫,都會委派給外部物件的 IUnknown

這三種行為使得彙總任何 Managed 物件得以實現。 使用這種類型的彙總關聯性 (Relationship),就可以將單一 COM 物件一部分實作在 Managed 程式碼中 (內部部分),一部分實作在 Unmanaged 程式碼中 (外部部分)。

內含項目

.NET 物件可以包含 COM 物件,方法是將它的中繼資料匯入至 .NET 組件,然後在其他類別中宣告這個型別的資料成員。 就如同一般的 COM內含項目一樣,您可以在您自己的介面實作中呼叫 COM 物件的介面,但是所包含的物件不會公開於類別之外。 內含項目比彙總要簡單一些。 您通常會在外部物件需要修改內部物件的行為時使用內含項目。 為了達成這一點,外部物件只是在它的建構函式中建立內部物件的執行個體,並且依需要將呼叫委派給內部物件。 外部物件可以選擇哪些呼叫要委派,哪些呼叫要直接處理。 執行階段對於支援內含項目沒有特別的物件需求。

COM 物件也可以包含 .NET 物件。 而其相對於 COM 物件用戶端的行為,就如同這個包含的物件就是任何其他 COM 物件一樣。

請參閱

概念

將 COM 元件公開給 .NET Framework

將 .NET Framework 元件公開給 COM

其他資源

進階 COM 互通性