2013-12-17 8 views
5

Ho una struttura che ha una tonnellata di membri bool denominati. (Si prega di lasciare le buone pratiche e tali fuori considerazione ora per il bene dell'esempio).Impostazione di tutti i membri bool di un oggetto mediante la riflessione

Desidero impostare in modo casuale questi valori su true o false, solo a scopo di test.

Come posso farlo attraverso la riflessione?

Questo è quello che ho finora:

 Random r = new Random(); 
     foreach (var bool_field in state.GetType().GetFields().Where(x => x.GetType() == false.GetType())) 
     { 
      bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false); 
     } 

Purtroppo, non entra mai il ciclo.

UPDATE 1:

Ecco come la struct SystemState sembra, che è il tipo di variabile diStato. È pieno di proprietà auto bool.

public struct SystemState 
{ 
    ... 
    public bool CanYouHelpMeOnThisOne { get; set; } 
    ... 
} 

UPDATE 2:

La soluzione postato qui sotto sembra bello, ma non funziona. Il motivo è che SystemState è una struttura non una classe. Perciò è un tipo di valore non un tipo di riferimento, quindi chiamare il metodo SetValue non ha alcun effetto. Dopo aver modificato SystemState in classe, la soluzione seguente funziona perfettamente.

Ora c'è un altro modo, per raggiungere questo senza cambiare SystemState in classe?

+1

@horgh: Supponendo che abbia alcuni membri 'bool' in là. –

+1

Solo una nota a margine: poiché sai al momento della compilazione che vuoi impostare i campi 'Boolean', userei' typeof (Boolean) 'piuttosto che' false.GetType() '. –

risposta

8

In un primo momento è necessario modificare la clausola Where:

x => x.FieldType == false.GetType() 

Come il tipo di x è FieldInfo


Dal modificare l'ultima del PO non è campi là, ma le proprietà. Quindi, è necessario utilizzare GetProperties per ottenere l'elenco di proprietà e confrontare il PropertyType, come x sarebbe PropertyInfo quindi. Anche il metodo SetValue avrà l'altra firma.

foreach (var bool_field in state.GetType() 
           .GetProperties() 
           .Where(x => x.PropertyType == false.GetType())) 
{ 
    bool_field.SetValue(state, r.Next() % 2 == 0 ? true : false, null); 
} 

Sulla base di commenti di OP, se si vuole accedere ai campi di supporto, è possibile utilizzare il seguente codice:

var fs = state.GetType() 
       .GetFields(BindingFlags.Instance | BindingFlags.NonPublic) 
       .Where(x => x.FieldType == typeof(bool)); 
foreach (var f in fs) 
{ 
    f.SetValue(state, true); 
} 

Il sovraccarico di GetFields senza argomenti restituisce tutti i campi pubblici del tipo corrente. Mentre nel tuo caso hai bisogno di quelli private, usa lo Type.GetFields Method (BindingFlags) con l'appropriato BindingFlags.

+0

Per quanto ne so a livello di assembly, esiste un campo di supporto per ogni proprietà auto. Non sono selezionati dal metodo GetFields() del tipo? – VSZM

+0

Puoi verificarlo facilmente con il tuo codice attuale ....ricorda solo di cambiare 'x.GetType()' in 'x.FieldType' – horgh

+0

Inoltre non sembra affatto utile lavorare direttamente con i campi di supporto. – horgh

Problemi correlati