views:

485

answers:

4

like in java I have:

Class.getSuperClass().getDeclaredFields()

how I can know and set private field from a superclass?

I know this is strongly not recommended, but I am testing my application and I need simulate a wrong situation where the id is correct and the name not. But this Id is private.

+1  A: 

This class will let you do it:

http://code.google.com/p/csharptest-net/source/browse/trunk/src/Library/Reflection/PropertyType.cs

Usage:

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

BTW, It will work on public/non-public fields or properties. For ease of use you can use the derived class PropertyValue like this:

new PropertyValue<int>(this,  "_myParentField").Value = newValue;
csharptest.net
+1 for the csharptest-net library. It has an interesting logger.
Steven Sudit
+5  A: 

Yes, it is possible to use reflection to set the value of a readonly field after the constructor has run

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

EDIT

Updated to look in the direct parent type. This solution will likely have issues if the types are generic.

JaredPar
but, with this code I can't get the parent field. alright?
Luís Custódio
@Luís, updated the code to look in the parent type
JaredPar
u now why I only can get my field using "<Id>k__BackingField"?
Luís Custódio
thanks !!! it helped
Tumbleweed
+1  A: 

Yes, you can.

For fields, use the FieldInfo class. The BindingFlags.NonPublic parameter allows you to see private fields.

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");
    }
}

and a small test to prove it works:

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

Like JaredPar suggests, I did the follow:

//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);

Thanks to all.

Luís Custódio
Are you sure that idFromBaseType[0] is the correct field? You probably should match by name...
Nader Shirazie
For me works, cause my first element is the ID. But I have tried get the field with string however with no success.
Luís Custódio