2012-10-21 22 views
18

Perché il seguente codice non funziona:valore Set di campo privato

class Program 
{ 
    static void Main (string[ ] args) 
    { 
     SomeClass s = new SomeClass(); 

     s.GetType().GetField("id" , System.Reflection.BindingFlags.NonPublic) // sorry reasently updated to GetField from GetProperty... 
      .SetValue(s , "new value"); 
    } 
} 


class SomeClass 
{ 
    object id; 

    public object Id 
    { 
     get 
     { 
      return id; 
     } 
    } 
} 

Sto cercando di impostare il valore di un campo privato.


Ecco eccettuati ottengo:

System.NullReferenceException era riferimento gestita Messaggio = Oggetto non impostato a un'istanza di un oggetto. Source = ConsoleApplication7
StackTrace: a Program.Main (String [] args) in C: \ Users \ Antonio \ Desktop \ ConsoleApplication7 \ ConsoleApplication7 \ Program.cs: linea a System.AppDomain._nExecuteAssembly (RuntimeAssembly assemblaggio, String [] args) a System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, string [] args) a Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() a System.Threading.ThreadHelper.ThreadStart_Context (stato oggetto) in System.Threading.ExecutionContext.Run (ExecutionContext executionContext, callback ContextCallback, stato dell'oggetto, booleano ignoreSyncCtx) in System.Threading.Executi onContext.Run (ExecutionContext ExecutionContext, ContextCallback callback, stato oggetto) a System.Threading.ThreadHelper.ThreadStart() InnerException:

+0

Puoi specificare "non funziona"? Cosa succede e in che cosa differisce da ciò che ti aspetti? Ricevi un messaggio di errore? – Guffa

+0

Provare a iterare attraverso GetFields() (manualmente usando il punto di interruzione del debugger) per vedere cosa viene restituito. Afaik, non vi è alcuna garanzia che l'ID della variabile rimarrà id nominativo, ma non ne sono sicuro. Inoltre, ho avuto problemi a ottenere proprietà/metodi privati ​​in precedenza e in genere viene risolto utilizzando BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance (ad esempio) – Alxandr

risposta

38

Prova questo (ispirato da Find a private field with Reflection?):

var prop = s.GetType().GetField("id", System.Reflection.BindingFlags.NonPublic 
    | System.Reflection.BindingFlags.Instance); 
prop.SetValue(s, "new value"); 

mie modifiche sono state per utilizzare il metodo GetField - si è ac cessare un campo e non una proprietà, e per o NonPublic con Instance.

+0

+1 - BindingFlags.Instance è la risposta. –

+0

sfortunatamente questo non funziona per le strutture. consente di impostare il valore della copia della struttura inviata a SetValue e la struttura originale rimane invariata. – SoLaR

1

Evidentemente, aggiungendo BindingFlags.Instance sembra aver risolto:

> class SomeClass 
    { 
     object id; 

     public object Id 
     { 
      get 
      { 
       return id; 
      } 
     } 
    } 
> var t = typeof(SomeClass) 
     ; 
> t 
[Submission#1+SomeClass] 
> t.GetField("id") 
null 
> t.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
> t.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) 
[System.Object id] 
> 
Problemi correlati