Reputation: 113976
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
Reputation: 7672
Well, since you cannot change the source code of the parent class, there's possibly 2 choices:
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).
You can indeed use reflection.
Upvotes: 2
Reputation: 459
No you cannot do it. Unless you use reflection for example:
Reflection.FieldInfo fields[] =
myType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
Upvotes: 1
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
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
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