Partilhar via


Reflexão em C++

reflexão permite que os tipos de dados conhecidos a serem inspecionadas no tempo de execução.reflexão permite a enumeração dos tipos de dados em um determinado assembly e os membros de um determinado tipo de classe ou um valor que podem ser descobertos.Isso é verdadeiro independentemente do tipo era conhecido ou referenciado em time de compilar.Isso torna a reflexão um recurso útil para desenvolvimento e ferramentas de gerenciamento de código.

Observe que o nome do assembly fornecido é o nome de alta segurança (consulte Assemblies com nome forte), que inclui a versão do assembly, cultura e informações de assinatura.Observe também que o nome do namespace no qual o tipo de dados está definido pode ser recuperado, juntamente com o nome da classe base.

A maneira mais comum para acessar os recursos de reflexão é por meio de GetType método. Este método é fornecido por sistema::objeto, da qual derivam todas as classes de coleta de lixo.

Reflexão em um .exe criados com o compilador do Visual C++ é permitido se o exe é construído com o /clr:pure ou /clr:safe Opções do compilador. Consulte o CLR (ComComummon Idioma Tempo de execução ComComumpilation) para obter mais informações.

Tópicos nesta seção:

Para obter mais informações, consulte

Exemplo

The GetType método retorna um ponteiro para um Type objeto de classe, que descreve o tipo ao quando o objeto se baseia. (The Tipo objeto não contém qualquer informação específica de instância.) sistema autônomo um item é o nome completo do tipo, que pode ser exibido da seguinte maneira:

Observe que o nome de tipo inclui o escopo completo no qual o tipo está definido, incluindo o espaço para nome, e que ela está visível na sintaxe .NET, com um ponto sistema autônomo o operador de resolução de escopo.

// vcpp_reflection.cpp
// compile with: /clr
using namespace System;
int main() {
   String ^ s = "sample string";
   Console::WriteLine("full type name of '{0}' is '{1}'", s, s->GetType());
}

full type name of 'sample string' is 'System.String'

Tipos de valor podem ser usados com o GetType função bem, mas eles devem ser processador pela primeira vez.

// vcpp_reflection_2.cpp
// compile with: /clr
using namespace System;
int main() {
   Int32 i = 100; 
   Object ^ o = i;
   Console::WriteLine("type of i = '{0}'", o->GetType());
}

type of i = 'System.Int32'

sistema autônomo ocorre com o GetType método, o typeID o operador retorna um ponteiro para um Tipo objeto, para que esse código indica o tipo de nome sistema.Int32.Exibir nomes de tipo é o recurso mais básico da reflexão, mas é uma técnica útil potencialmente mais inspecionar ou descobrir os valores válido para os tipos enumerados.Isso pode ser concluído usando o estáticoEnum::GetNames função, que retorna uma matriz de cadeias de caracteres, cada uma contendo um valor de enumeração na forma de texto.O exemplo a seguir recupera uma matriz de seqüências de caracteres que descreve os valores de enumeração do valor para o Opções Enum (CLR) e os exibe em um loop.

Se uma quarta opção for adicionada à Opções enumeração, esse código relatará a nova opção sem recompilação, mesmo que a enumeração é definida em um assembly separado.

// vcpp_reflection_3.cpp
// compile with: /clr
using namespace System;

enum class Options {   // not a native enum
   Option1, Option2, Option3
};

int main() {
   array<String^>^ names = Enum::GetNames(Options::typeid);

   Console::WriteLine("there are {0} options in enum '{1}'", 
               names->Length, Options::typeid);

   for (int i = 0 ; i < names->Length ; i++)
      Console::WriteLine("{0}: {1}", i, names[i]);

   Options o = Options::Option2;
   Console::WriteLine("value of 'o' is {0}", o);
}

there are 3 options in enum 'Options' 0: Option1 1: Option2 2: Option3 value of 'o' is Option2

The GetType objeto oferece suporte a um número de membros e propriedades que podem ser usadas para examinar um tipo. Este código recupera e exibe algumas dessas informações:

// vcpp_reflection_4.cpp
// compile with: /clr
using namespace System;
int main() {
   Console::WriteLine("type information for 'String':");
   Type ^ t = String::typeid;

   String ^ assemblyName = t->Assembly->FullName;
   Console::WriteLine("assembly name: {0}", assemblyName);

   String ^ nameSpace = t->Namespace;
   Console::WriteLine("namespace: {0}", nameSpace);

   String ^ baseType = t->BaseType->FullName;
   Console::WriteLine("base type: {0}", baseType);

   bool isArray = t->IsArray;
   Console::WriteLine("is array: {0}", isArray);

   bool isClass = t->IsClass;
   Console::WriteLine("is class: {0}", isClass);
}

type information for 'String': assembly name: mscorlib, Version=1.0.5000.0, Culture=neutral,  PublicKeyToken=b77a5c561934e089 namespace: System base type: System.Object is array: False is class: True

Reflexão também permite a enumeração de tipos em um assembly e os membros nas classes.Para demonstrar esse recurso, defina uma classe simples:

// vcpp_reflection_5.cpp
// compile with: /clr /LD
using namespace System;
public ref class TestClass {
   int m_i;
public:
   TestClass() {}
   void SimpleTestMember1() {}
   String ^ SimpleMember2(String ^ s) { return s; } 
   int TestMember(int i) { return i; }
   property int Member {
      int get() { return m_i; }
      void set(int i) { m_i = i; }
   }
};

Se o código acima é compilado em uma DLL chamada vcpp_reflection_6.dll, em seguida, você pode usar reflexão para inspecionar o Sumário deste assembly.Isso envolve usando a reflexão de função API estáticoAssembly::Load para carregar o assembly.Esta função retorna o endereço de um Assembly objeto, em seguida, pode ser consultado sobre os módulos e tipos de dentro.

Depois que o sistema de reflexão carrega com êxito o conjunto, uma matriz de Tipo objetos são recuperados com o Assembly::GetTypes função.Cada elemento da matriz contém informações sobre um tipo diferente, embora nesse caso, apenas uma classe é definida.Usando um loop, cada Tipo nessa matriz é consultado sobre os membros de tipo usando o Type::GetMembers função.Esta função retorna uma matriz de MethodInfo objetos, cada objeto que contém informações sobre a função de membro, membro de dados ou propriedade no tipo.

Observe que a lista de métodos inclui as funções explicitamente definidas em TestClass e as funções herdadas implicitamente do sistema::objeto classe.sistema autônomo parte do que está sendo descrito em .NET em vez de sintaxe do Visual C++, sistema autônomo propriedades aparecem sistema autônomo o membro de dados subjacentes acessado por funções get/conjunto.sistema autônomo funções get/conjunto aparecem nesta lista sistema autônomo métodos regulares.Reflexão é suportado através do common linguagem tempo de execução, não pelo compilador Visual C++.

Embora usado esse código para inspecionar um assembly que você definiu, você também pode usar este código para inspecionar os assemblies .NET.Por exemplo, se você alterar TestAssembly para mscorlib, você verá uma lista de cada tipo e o método definido no mscorlib.dll.

// vcpp_reflection_6.cpp
// compile with: /clr
using namespace System;
using namespace System::IO;
using namespace System::Reflection;
int main() {
   Assembly ^ a = nullptr;
   try {
      // load assembly -- do not use file extension
      // will look for .dll extension first
      // then .exe with the filename
      a = Assembly::Load("vcpp_reflection_5");
   }
   catch (FileNotFoundException ^ e) {
      Console::WriteLine(e->Message);
      return -1;
   }

   Console::WriteLine("assembly info:");
   Console::WriteLine(a->FullName);
   array<Type^>^ typeArray = a->GetTypes();

   Console::WriteLine("type info ({0} types):", typeArray->Length);

   int totalTypes = 0;
   int totalMembers = 0;
   for (int i = 0 ; i < typeArray->Length ; i++) {
      // retrieve array of member descriptions
      array<MemberInfo^>^ member = typeArray[i]->GetMembers();

      Console::WriteLine("  members of {0} ({1} members):", 
      typeArray[i]->FullName, member->Length);
      for (int j = 0 ; j < member->Length ; j++) {
         Console::Write("       ({0})", 
         member[j]->MemberType.ToString() );
         Console::Write("{0}  ", member[j]);
         Console::WriteLine("");
         totalMembers++;
      }
      totalTypes++;
   }
   Console::WriteLine("{0} total types, {1} total members",
   totalTypes, totalMembers);
}

Consulte também

Outros recursos

Guia de programação .NET