Accedere a membri internal o private

di Cristian Civera, in .NET,

Come al solito, un bel giorno mi sono chiesto come i formatters (BinaryFormatter e SoapFormatter) potessero serializzare e deserializzare membri di classi anche private o internal. E' infatti impossibile programmando normalmente: nel primo caso bisogna dovremmo trovarci nella stessa classe del membro, nel secondo, almeno nello stesso assembly.

Ho pensato quindi che l'unica soluzione era l'uso della reflection. Sebbene non ho trovato nei formatters righe di codice che usino le classi del namespace System.Reflection (non è semplice, è abbastanza complesso) ho fatto un po' di prove. Una volta ottenuto un riferimento al Type possiamo accedere a tutti i metadati e a qualsiasi membro, ottenere informazioni su di esso e prelevare o impostare, data l'istanza dell'oggetto, il valore di un field o richiamare un suo metodo (quindi anche le proprietà o eventi).

Penso che possa risultare utile in certe situazioni sebbene con minori performance. Per esempio la classe HttpRequest ha una proprietà LocalAddress che restituisce l'ip della macchina.
Per ottenere il valore faremo:

Type t = Request.GetType();
PropertyInfo pi = t.GetProperty("LocalAddress", BindingFlags.NonPublic | BindingFlags.Instance);
object value = pi.GetValue(Request, null);
Response.Write(value.ToString());

Il BindingFlags è necessario per indicare il range di membri nella quale deve cercare (più è preciso meglio è quindi). Il secondo paramentro di GetValue vuole un array di object, per le proprietà paramentriche.

A volte è utile è sapere la pagina di Login specificata nella sezione "authentication". La chiamata GetConfig darà un tipo AuthenticationConfig. Basta guardare con il Reflector che membri ha e possiamo fare tutto c'ho che vogliamo:

object config = Context.GetConfig("system.web/authentication");
Type t2 = config.GetType();
PropertyInfo pi2 = t2.GetProperty("LoginUrl", BindingFlags.NonPublic | BindingFlags.Instance);
object value2 = pi2.GetValue(config, null);
Response.Write(value2.ToString());
Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese