2009-09-09 11 views

risposta

9

Sì, è possibile utilizzare la reflection per impostare il valore di un campo di sola lettura dopo il costruttore ha eseguito

var fi = this.GetType() 
      .BaseType 
      .GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic); 

fi.SetValue(this, 1); 

EDIT

Aggiornato per cercare il tipo di genitore diretto. Questa soluzione avrà probabilmente problemi se i tipi sono generici.

+0

ma, con questo codice non riesco a ottenere il campo genitore. tutto apposto? – Custodio

+0

@ Luís, ha aggiornato il codice per cercare il genitore tipo – JaredPar

+0

e ora perché posso solo ottenere il mio campo usando " k__BackingField"? – Custodio

1

Questa classe vi permetterà di farlo:

http://csharptest.net/browse/src/Library/Reflection/PropertyType.cs

Usage:

new PropertyType(this.GetType(), "_myParentField").SetValue(this, newValue); 

BTW, Si lavorerà su campi o proprietà pubbliche/non pubbliche. Per facilità d'uso è possibile utilizzare la classe derivata PropertyValue come questo:

new PropertyValue<int>(this, "_myParentField").Value = newValue; 
+0

+1 per la libreria csharptest-net. Ha un logger interessante. –

1

Sì, è possibile.

Per i campi, utilizzare la classe FieldInfo. Il parametro BindingFlags.NonPublic consente di visualizzare i campi privati.

public class Base 
{ 
    private string _id = "hi"; 

    public string Id { get { return _id; } } 
} 

public class Derived : Base 
{ 
    public void changeParentVariable() 
    { 
     FieldInfo fld = typeof(Base).GetField("_id", BindingFlags.Instance | BindingFlags.NonPublic); 
     fld.SetValue(this, "sup"); 
    } 
} 

e un piccolo test per dimostrare che funziona:

public static void Run() 
{ 
    var derived = new Derived(); 
    Console.WriteLine(derived.Id); // prints "hi" 
    derived.changeParentVariable(); 
    Console.WriteLine(derived.Id); // prints "sup" 
} 
0

Come suggerisce JaredPar, ho fatto la seguente:

//to discover the object type 
Type groupType = _group.GetType(); 
//to discover the parent object type 
Type bType = groupType.BaseType; 
//now I get all field to make sure that I can retrieve the field. 
FieldInfo[] idFromBaseType = bType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 

//And finally I set the values. (for me, the ID is the first element) 
idFromBaseType[0].SetValue(_group, 1); 

Grazie a tutti.

+0

Sei sicuro che idFromBaseType [0] è il campo corretto? Probabilmente dovresti abbinare per nome ... –

+0

Per me funziona, perché il mio primo elemento è l'ID. Ma ho provato a ottenere il campo con la stringa, ma senza successo. – Custodio

Problemi correlati