C# - Como acessar um método privado fora da classe


Hoje veremos como acessar um método private fora da sua classe na linguagem C#.

Creio que você já deve saber que um método privado é um método de classe que só pode ser chamado de dentro da classe declarante. Se você tentar acessar um private de fora da sua classe , seu código simplesmente não compilará.

A prova dos nove

Vamos criar um projeto Console no VS 2022 e neste projeto criar uma classe com um método privado:

Agora vamos tentar acessar este método criando uma instância da classe no arquivo Program:

Obs:  O código acima esta usando o recurso Top Level Statements do C# 9.

A mensagem exibida deixa claro que o método esta inacessível devido ao seu nível de proteção.

Acessando o método privado com Reflection

Um programa pode olhar para os metadados de outros assemblies ou de si mesmo, enquanto ele está executando. Quando um programa em execução olha para seus próprios metadados, ou de outros programas, a ação é chamada de Reflection.

Nota: Os metadados são informações sobre os dados, ou seja, informações sobre os tipos, o código, assembly e assim por diante - que é armazenada junto com seu programa.

Dessa forma, Reflection é o processo pelo qual um programa pode ler seus próprios metadados. Um programa que faz Reflection sobre si mesmo, extrai metadados de sua montagem e usa estes metadados ou para informar ao usuário ou para modificar o seu próprio comportamento.

Então, Reflection é a capacidade de ler metadados em tempo de execução. Usando Reflection, é possível descobrir os métodos, propriedades e eventos de um tipo, e a seguir invocá-los dinamicamente. Usando Reflection podemos também criar novos tipos em tempo de execução.

Desta forma nem tudo esta perdido para o nosso caso e podemos usar o recurso Reflection para obter informações de um método e até mesmo invocar o método privado de uma classe.

Para fazer isso basta usar o código abaixo:

using System.Reflection;

Console.WriteLine("\nTentando acessar o método privado da classe MinhaClasse\n");
Console.Read();

typeof(MinhaClasse)
     .
GetMethod("MeuMetodoPrivado", BindingFlags.NonPublic | BindingFlags.Instance)
     .
Invoke(new MinhaClasse(), null);

 

O resultado será a execução do método:

Uma outra forma de acessar o método privado é aplicar o atributo InternalsVisibleTo a nível do assembly.

Para usar este recurso podemos usar o atributo InternalsVisibleToAttribute no arquivo AssemblyInfo.cs no qual permite tornar os métodos private visíveis para os tipos em um assembly especificado, que é conhecido como um assembly Friend.

Isso significa que ele pode ser incluído no início de um arquivo de código-fonte ou pode ser incluído no arquivo AssemblyInfo em um projeto do Visual Studio.

Você pode usar o atributo para especificar um único assembly Friend que possa acessar os tipos internos e os membros do assembly atual. 

Uma forma é usá-los como atributos individuais no nível do assembly, como ilustra o exemplo a seguir.

[assembly:InternalsVisibleTo("Classe1")]
[assembly:InternalsVisibleTo("Classe2")]

E estamos conversados...

"Se alguém não estiver em mim, será lançado fora, como a vara, e secará; e os colhem e lançam no fogo, e ardem. Se vós estiverdes em mim, e as minhas palavras estiverem em vós, pedireis tudo o que quiserdes, e vos será feito."
João 15:6,7

Referências:


José Carlos Macoratti