LA.Net
Reflexões sobre C#, .Net e programação em geral

Pois é...afinal, os qualificadores aplicados aos métodos/propriedades são apenas usadas pelos compiladores das linguagens que utilizamos (ex.: C# ou VB.Net). Se for necessário podemos evocar um método protegido (ou, se preferirem, privado) através de Reflection. O exemplo seguinte demonstra como podemos fazer isto:

namespace TestHidden
{
  class MyClass
  {
     private void HiddenMethod( )
     {
       Console.WriteLine( "oopss...you've justinvoked a hidden method!" );
     }
  } 
  class Program
  {
    static void Main( string [] args )
    {
      MyClass aux = new MyClass( );
      Type tp = aux.GetType();
          tp.InvokeMember( "HiddenMethod", System.Reflection.BindingFlags.Instance |
          System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic, null, aux, null );
    }
  }
}

E lá se foi a protecção que fornecemos aos nossos métodos :) Claro que até podemos perceber porque é que isto é possível...Bom, a pergunta que se segue: será que podemos impedir que isto aconteça? Por acaso até podemos: basta utilizar o atributo ReflectionPermissionAttribute. Com este atributo podemos controlar o acesso que é efectuado aos nossos elementos (ou melhor, ao nosso assembly, uma vez que este atributo não pode ser aplicado a tipos nem a métodos) através de operações executadas através de reflection. Experimentem adicionar esta linha ao código anterior e vejam lá o resultado obtido:

[assembly: ReflectionPermission(SecurityAction.RequestRefuse, Unrestricted = true)]

Bom, se pensam que agora podem "dormir descansados", então estão enganados. Por acaso é possível contornar esta "imposição" se estivermos dispostos desactivar o sistema de segurança que controla o acesso ao código. Para tal basta recorrermos à propriedade (estática)  SecurityEnabled da classe SecurityManager. Para experimentarem, basta colocarem o código que recorre ao Reflection rodeado pelas seguintes linhas

SecurityManager.SecurityEnabled = false;
//código que executa o método através de reflection
SecurityManager.SecurityEnabled = true;

Portanto, não há nada a fazer :) Afinal, todos os métodos que escrevemos são públicos...ou, melhor, podem ser executados. Claro que o recurso a este tipo de situações só deve ser utilizado em último recurso. A LAGridView (o controlo que já estou para publicar há alguns dias :) - desculpem o atraso, mas com o Natal e o Fim do Ano acabei por não ter tempo de escrever o artigo) recorre a este tipo de situações pois necessita de evocar o método da classe base que foi implementado de forma privada (a justificação para isto está aqui).

Não iria dormir descansado se não chamasse (mais uma vez) à atenção para o facto deste tipo de acções deverem ser consideradas apenas em último recurso. Afinal de contas, se o constructor da classe definiu o método como privado, então deve ter tido uma boa razão para proceder dessa forma. Para além disso, convém ainda notar que uma classe não é obrigada a manter um método privado (quanto mais manter o código colocado no interior desse método!) pois este não faz parte do contracto da classe.

posted on Sunday, January 02, 2005 10:58 PM
Comments
  • # re: Aha! O meu método privado afinal é...público
    Vinicius Dias
    Posted @ 1/6/2005 12:53 PM
    Gostaria de tirar uma dúvida?
    Se estes códigos de classes estivessem em arquivos diferentes , ou seja compilados em .cs diferentes , a classe Program não teria como saber o nome do método private , pois na linha:
    - tp.InvokeMember( "HiddenMethod", ....
    vc especifica o nome do método (HiddenMethod) ,certo? Como ficaria?
  • # re: Aha! O meu método privado afinal é...público
    Luis Abreu
    Posted @ 1/6/2005 3:57 PM
    Podias sempre enumerar todos os metodos. Por exemplo, podes utilizar o .net reflector para consultares os metodos existentes numa classe (e consegues ver tudo: desde campos, propriedades, metodos, etc independentemente de serem privados ou nao).
  • # re: Aha! O meu método privado afinal é...público
    尖锐湿疣
    Posted @ 4/25/2005 7:48 AM
    Thank You!
Title  
Name  
Url
Box Code
Protected by FormShield
Comments