Compartilhar via


Apresentando a interface de classe

A interface de classe, que não está explicitamente definida no código gerenciado, é uma interface que expõe todos os métodos públicos, propriedades, campos e eventos que são explicitamente expostos no objeto .NET.Esta interface pode ser uma interface dupla ou despacho somente.A interface de classe recebe o nome da classe .NET propriamente dito, precedido por um sublinhado.Por exemplo, para classe mamífero, a interface de classe é _Mammal.

Para classes derivadas, a interface de classe também expõe todos os campos da classe base, propriedades e métodos públicos.A classe derivada também expõe uma interface de classe para cada classe de base.Por exemplo, se a classe mamífero estende classe MammalSuperclass, que por si só estende sistema.Object, expõe o objeto .NET para COM clientes três interfaces de classe _Mammal, _MammalSuperclass e _Object.

Por exemplo, considere a classe .NET a seguir:

' Applies the ClassInterfaceAttribute to set the interface to dual.
<ClassInterface(ClassInterfaceType.AutoDual)> _
' Implicitly extends System.Object.
Public Class Mammal
    Sub Eat()
    Sub Breathe()
    Sub Sleep()
End Class
// Applies the ClassInterfaceAttribute to set the interface to dual.
[ClassInterface(ClassInterfaceType.AutoDual)]
// Implicitly extends System.Object.
public class Mammal
{
    void  Eat();
    void  Breathe():
    void  Sleep();
}

O cliente COM pode obter um ponteiro para uma interface de classe chamada _Mammal, que é descrito na biblioteca de tipos que o Tipo Library Exporter (Tlbexp.exe) ferramenta gera.Se o Mammal classe implementada uma ou mais interfaces, interfaces seriam exibida sob o coclass.

   [odl, uuid(…), hidden, dual, nonextensible, oleautomation]
   interface _Mammal : IDispatch
   {
       [id(0x00000000), propget] HRESULT ToString([out, retval] BSTR*
           pRetVal);
       [id(0x60020001)] HRESULT Equals([in] VARIANT obj, [out, retval]
           VARIANT_BOOL* pRetVal);
       [id(0x60020002)] HRESULT GetHashCode([out, retval] short* pRetVal);
       [id(0x60020003)] HRESULT GetType([out, retval] _Type** pRetVal);
       [id(0x6002000d)] HRESULT Eat();
       [id(0x6002000e)] HRESULT Breathe();
       [id(0x6002000f)] HRESULT Sleep();
   }
   [uuid(…)]
   coclass Mammal 
   {
       [default] interface _Mammal;
   }

Gerando a classe interface é opcional.Por padrão, a interoperabilidade COM gera uma interface somente de despacho para cada classe de que exportar para uma biblioteca de tipos.Você pode evitar ou modificar a criação automático dessa interface, aplicando o ClassInterfaceAttribute à sua classe. Embora a interface de classe pode facilitar a tarefa de expor gerenciado classes COM, seus usos são limitados.

Cuidado:

Usando a interface de classe, em vez de explicitamente definir seu próprio, podem complicar as versões futuras da sua classe gerenciada.Leia as seguintes diretrizes antes de usar a interface de classe.

Defina uma interface explícita para clientes COM para uso em vez de gerar a interface de classe.

Como a interoperabilidade COM gera automaticamente uma interface de classe, post-versão alterações em sua classe podem alterar o layout da interface da classe exposto pelo common linguagem tempo de execução.Como os clientes COM são normalmente não preparados lidar com alterações no layout de uma interface, eles serão desfeitos se você alterar o layout de membro da classe.

Essa diretriz reforça a noção que interfaces expostas para clientes COM permaneça inalterável.Para reduzir o risco de quebrar clientes COM por inadvertidamente reorganizando o layout da interface, isole todas as alterações à classe do layout da interface definindo explicitamente as interfaces.

Use o ClassInterfaceAttribute para desengatar a geração automático de interface de classe e implementar uma interface explícita para a classe, sistema autônomo o fragmento de código a seguir mostra:

<ClassInterface(ClassInterfaceType.None)>Public Class LoanApp
    Implements IExplicit
    Sub M() Implements IExplicit.M
…
End Class
[ClassInterface(ClassInterfaceType.None)]
public class LoanApp : IExplicit {
    void M();
}

The ClassInterfaceType.Nonevalor de evita que a interface de classe seja gerado quando metadados da classe é exportado para uma biblioteca de tipos.No exemplo anterior, COM clientes podem acessar o LoanApp somente por meio da classe a IExplicit interface.

Evite o armazenamento em cache os identificadores de despacho (DispIds).

Usando a interface de classe é uma opção aceitável para clientes com script, os clientes do Microsoft Visual Basic 6.0 ou qualquer atraso-limite cliente não armazena em cache DispIds de membros de interface.DispIds identificar membros de interface para habilitar associação tardia.

Interface da classe, geração de DispIds é baseada na posição do membro na interface.Se você alterar a ordem de membro e exporta a classe para uma biblioteca de tipos, você alterará DispIds gerado na interface de classe.

Para evitar a interrupção de ligação tardia COM clientes ao usar a interface de classe, aplique o ClassInterfaceAttribute with the ClassInterfaceType.AutoDispatchvalor de .Esse valor implementa uma interface de classe de despacho, mas omite a descrição da interface de biblioteca de tipos.Sem uma descrição da interface, clientes não conseguem cache DispIds em time de compilar.Embora esse seja o tipo de interface padrão para a interface de classe, você pode aplicar o valor do atributo explicitamente.

<ClassInterface(ClassInterfaceType.AutoDispatch)> Public Class LoanApp
    Implements IAnother
    Sub M() Implements IAnother.M
…
End Class
[ClassInterface(ClassInterfaceType.AutoDispatch]
public class LoanApp : IAnother {
    void M();
}

Para obter DispId de um membro da interface em time de execução, clientes COM podem chamar IDispatch.GetIdsOfNames.Para chamar um método na interface, passe DispId retornado sistema autônomo um argumento para IDispatch.Invoke.

Restringir usando a opção de interface dupla para a interface de classe.

Ligação antecipada e atrasada para membros de interface por clientes COM permitem que duas interfaces.Em time de design e durante o teste, talvez seja útil para conjunto a interface de classe para dois.Para um gerenciado classe (e suas classes base) que nunca será modificada, essa opção também é aceitável.Em outros casos, evite configurar a interface de classe para dois.

Uma interface dupla gerada automaticamente pode ser adequada em casos raros; no entanto, com mais freqüência cria relacionados à versão complexidade.Por exemplo, clientes COM usando a interface de classe de uma classe derivada podem com com facilidade interromper com as alterações a classe base.Quando um terceiro fornece a classe base, o layout da interface da classe está fora do seu controle.Além disso, ao contrário de uma interface de despacho somente uma interface dupla (ClassInterface.AutoDual) Fornece uma descrição da interface de classe na biblioteca de tipos exportada.Como uma descrição incentiva os clientes de ligação tardia cache DispIds em time de execução.

Consulte também

Conceitos

COM callable wrapper

Qualificação de tipos do .NET para interoperação

Referência

ClassInterfaceAttribute