1

次のように、別のインターフェイスから継承するインターフェイスがあります。

[
    object,
    uuid(72A6E473-9956-4856-A335-B9169359AACE),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IA : IDispatch
{
    HRESULT MethodA();
}

[
    object,
    uuid(378846D3-7E24-4DAE-B4DF-69AA4B0C1AA9),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IB : IA
{
    HRESULT MethodB();
}

[
    object,
    uuid(4C187526-6809-4A57-A3ED-626E0B36F7DB),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface ICollection : IDispatch
{
    HRESULT GetObject([out, retval] IA** ppValue);
}

ICollection の実装は、IB を実装するオブジェクトを返します。そのオブジェクトは、ディスパッチ インターフェイスを介して MethodA および MethodB へのアクセスを提供します。実行時にメンバーが追加されることはありません。

この場合、IA の非拡張属性は許可されますか?

4

1 に答える 1

1

この場合、IA の非拡張属性は許可されますか?

はい、そうです。

[nonextensible]typelib type flag に変換されたインターフェイスの属性には、 TYPEFLAG_FNONEXTENSIBLEVisual Basic (6 またはアプリケーションの場合) に、基礎となるIDispatch.

Dim A As IA
Set A = Obj ' QueryInterface
A.MethodA
' Compilation error
' A.MethodB
' If A.Property Then A.MethodC

Dim B As IB
Set B = Obj ' QueryInterface
B.MethodA
B.MethodB
' Compilation error
' If B.Property Then B.MethodC

がない[nonextensible]と、Visual Basic は不足しているメソッド呼び出しとプロパティ アクセスをコンパイルしIDispatch::GetIDsOfNamesますIDispatch::Invoke

一般に、これは、コンパイル時のチェックを優先し、動的ルックアップが必要な場合、Objectまたは必要な場合に変数を宣言するようにコードに強制する場合に適しています。Variantexpando オブジェクトでは面倒かもしれませんが、いずれにしてもIDispatchの契約の1 点に違反します。

IDispatch::GetIDsOfNames メソッド
…<br /> 解説
…<br /> メンバとパラメータの DISPID は、オブジェクトの存続期間中一定のままである必要があります。これにより、クライアントは一度 DISPID を取得し、後で使用できるようにキャッシュできます。
…<br /> 注意 このメソッドを使用して、JavaScript によって追加された値など、動的に追加された値にアクセスすることはできません。代わりに、IDispatchEx インターフェイスの GetDispID を使用してください。詳細については、IDispatchEx インターフェイスを参照してください。
…<br />


Alt編集: Word VBA ( + ) で試すことができるサンプルを次に示しますF11。マクロを追加して、このテキストを貼り付けます。

Dim Docs As Documents
Set Docs = Application.Documents
Docs.Add
' Compilation error
' Docs.Foo
Dim Doc As Document
Set Doc = Docs(0)
Doc.Activate
Doc.Foo

試してみるには、メニューの [デバッグ] → [プロジェクトをコンパイル] を選択します。

正常にコンパイルされるはずです。(デフォルトの) インターフェース (for)にはメソッドDocumentがありませんが、そうではないため(二重否定に注意してください)、呼び出しはランタイム ディスパッチになります。Foo[nonextensible]

ここで、プロジェクトのコメントDocs.Fooを外して再コンパイルします。

(デフォルト) インターフェース (for)Documents[nonextensible]あり、不足しているメソッドへの呼び出しがFooランタイム ディスパッチに変換されないため、エラーがスローされるはずです。

于 2014-07-11T00:56:02.927 に答える