C# - Usando Reflection (revisitado) - I


 Neste artigo vamos recordar o conceito de Reflection e sua utilização na linguagem C#.

O conceito de Reflection ou reflexão em C# é a capacidade de inspecionar metadados de assemblies em tempo de execução, o que significa que o conteúdo do assembly é descrito observando os metadados do assembly no namespace em tempo de execução.

Usando Reflection podemos inspecionar o código em tempo de execução (runtime) e realizar tarefas como :

Dessa forma podemos usar Reflection para realizar uma programação genérica onde podemos generalizar o código onde os nomes das propriedades e métodos podem variar.

O namespace System.Reflection define os seguintes tipos para analisar os metadados do módulo de uma assembly:  Assembly, Module, Enum, ParameterInfo, MemberInfo, Type, MethodInfo, ConstructorInfo, FieldInfo, EventInfo e PropertyInfo e fornece objetos que encapsulam assemblies, módulos e tipos.

Neste artigo veremos como obter de uma classe específica informações sobre métodos, propriedades, campos, e construtores usando reflection.

Podemos fazer isso usando Early Binding ou Late Binding.

Então vejamos o conceito de cada abordagem:

Early Binding (Vinculação Antecipada)

Significa que o compilador conhece o tipo de objeto, seus métodos e as propriedades que ele contém, ou seja, as informações sobre o objeto, método, classe, etc, são encontradas em tempo de compilação. Assim, quando você usa um objeto o Intellisense usa o early binding para preencher suas propriedades, métodos, eventos, etc, exibindo-as.

Late Binding (Vinculação Tardia)

Significa que o compilador não reconhece e não sabe o tipo de objeto que esta sendo usado, também não conhece os métodos, propriedades, eventos, etc. que o objeto contém. O tipo do objeto não é determinado em tempo de compilação. As informações sobre o objeto serão procuradas em tempo de execução.

Agora vamos ao nosso exemplo.

Considere uma classe Cliente que possui:

A seguir vamos definir esta classe e mostrar como usar Reflection para obter informações sobre o tipo definido usando Early Binding.

Recursos Usados:

Criando o projeto Console

Abra o VS 2017 Community e crie um projeto do tipo Console Application com o nome CShp_Reflection.

A seguir no menu Project clique em Add Class e informe o nome Cliente e o código abaixo nesta classe:

using static System.Console;
namespace CShp_Reflection
{
    public class Cliente
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public Cliente(int id, string nome)
        {
            this.Id = id;
            this.Nome = nome;
        }
        public Cliente()
        {
            this.Id = -1;
            this.Nome = string.Empty;
        }
        public void ImprimeID()
        {
            WriteLine($"ID = {this.Id}");
        }
        public void ImprimeNome()
        {
            WriteLine($"Nome = {this.Nome}");
        }
    }
}

Nesta classe temos :

Obtendo informações da classe Cliente usando Reflection

Vamos agora usar o namespace System.Reflection e extrair informações da classe Cliente usando Reflection.

Para isso inclua o código abaixo no método Main() da classe Program:

using System;
using System.Reflection;
using static System.Console;
namespace CShp_Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            // Obtém o Tipo usando o método estático GetType()
            Type T = Type.GetType("CShp_Reflection.Cliente");
            // Imprime os detalhes do Tipo
            WriteLine($"Nome Completo = {T.FullName}");
            WriteLine($"Apenas o nome da Classe = {T.Name}");
            WriteLine($"Apenas o namespace = {T.Namespace}");
            WriteLine();
            
            // Imprime a lista de métodos
            WriteLine("Metodos na classe Cliente");
            MethodInfo[] methods = T.GetMethods();
            foreach (MethodInfo method in methods)
            {
                // Imprime o tipo de Retorno e o nome do método
                WriteLine(method.ReturnType.Name + " " + method.Name);
            }
            WriteLine();
            //  Imprime as Propriedades
            WriteLine("Propriedades na classe Cliente");
            PropertyInfo[] properties = T.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                // Imprime o tipo e nome da propriedade
                WriteLine(property.PropertyType.Name + " " + property.Name);
            }
            WriteLine();
            //  Imprime os construtores
            WriteLine("Construtores na classe Cliente");
            ConstructorInfo[] constructors = T.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                WriteLine(constructor.ToString());
            }
            ReadLine();
        }
    }
}  

Obs : No código eu estou usando os recursos using static e interpolação de strings($) disponíveis a partir da versão 6.0 da linguagem c#

Neste código para obter o tipo de classe do cliente, usamos o método estático GetType() definido na classe Type.

Passamos o nome totalmente qualificado do tipo, incluindo o namespace como parâmetro para o método GetType().
Type T = Type.GetType ("CShp_Reflection.Cliente");

Para obter a informação do tipo temos duas opções:

1- Usar a palavra-chave typeof
Type T = typeof (Cliente);

2- Usar GetType() na instância da classe Cliente.
Cliente C1 = new Cliente();
Type T = C1.GetType ();

Para obter a informação dos métodos, usamos Type.GetMethods(), que retorna a matriz MethodInfo[] e, depois usamos Type.GetProperties() para obter informações de propriedades, que retorna a matriz PropertyInfo[].

A seguir usamos o método GetConstructors() para obter informações dos construtores.

Na próxima parte do artigo vamos veremos como podemos usar o Late Binding neste cenário.

"Mas nós não recebemos o espírito do mundo, mas o Espírito que provém de Deus, para que pudéssemos conhecer o que nos é dado gratuitamente por Deus. "
1 Coríntios 2:12

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti