Robin Rodricks
Robin Rodricks

Reputation: 113976

Can you modify a private field of a super class?

I'm working with a closed-source base class. Can I somehow change a private field in the base class from my inheriting class?

Assuming the following class structure:

public class Parent
{
    private bool age;
}

public class Baby : Parent  
{
    public bool newAge{
        get {
           return age;
        }
    }
}

This currently gives you a compile-time error:

 'Parent.age' is inaccessible due to its protection level.

How do you access the field "age" from the Baby class? Can you use reflection or something similar?

Upvotes: 2

Views: 2314

Answers (5)

everag
everag

Reputation: 7672

Well, since you cannot change the source code of the parent class, there's possibly 2 choices:

  1. If the parent class is a partial class, you can define your own contribution (another Parent class) defining a public Property (it can access private fields).

  2. You can indeed use reflection.

Upvotes: 2

rcarrillopadron
rcarrillopadron

Reputation: 459

No you cannot do it. Unless you use reflection for example:

Reflection.FieldInfo fields[] = 
    myType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

Upvotes: 1

Austin Salonen
Austin Salonen

Reputation: 50225

You can modify those values via reflection. That being said, you probably shouldn't.

Private fields, properties, and methods are all things that are not explicitly guaranteed by the contract of the class. If this 3rd-party API is reliable the public contracts they provide will not change (but they can easily grow).

The private and internal parts are not guaranteed to be the same from release to release. By coupling your code to those parts of the code, you've introduced a lot of risk to your future releases. If you're ok with that risk (and it's well-documented as to why you're doing it), the by all means, reflect away.

If you do go that route, I would recommend an Adapter class that all your consuming code uses instead of this 3rd-party API. With the Adapter pattern, only the one class will need to change in response to the 3rd-part API changes.

Upvotes: 2

vcsjones
vcsjones

Reputation: 141638

You could, using reflection. It looks like this:

public class Baby : Parent
{
    private readonly FieldInfo _ageField = typeof(Parent).GetField("age", BindingFlags.NonPublic | BindingFlags.Instance);
    public int newAge
    {
        get
        {
            return (int)_ageField.GetValue(this);
        }
        set
        {
            _ageField.SetValue(this, value);
        }
    }
} 

If it's provided by a 3rd party, there is nothing stopping them from changing it, renaming it, it removing it all together. That's one of the points of private. Keep in mind that it might be private for a reason. Tinkering where you aren't suppose to can lead to unexpected results.

Upvotes: 6

Tudor
Tudor

Reputation: 62439

You can try to use reflection to get access to private fields and modify them. Like:

typeof(Parent)
.GetField("age", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(parent, 14);

where parent is an instance of Parent.

Upvotes: 4

Related Questions