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