Reputation: 25014
I've got a base class from an outside library that I can't modify - here's the relevant piece:
public class BaseClass
{
List<string> _values;
public Values { get { return _values; } }
}
I am inheriting the BaseClass, and I want to set _values to a class that inherits from List(T) in the constructor:
public InheritingClass : BaseClass
{
public InheritingClass():base()
{
//set base._values = new InhertingList<string>(); ?
}
}
What's the best way to set base._values there? Is there a way to find what private variable is fetched by Values and set that in case the private variable is renamed in the future?
There are other ways I can accomplish what I need to do, but if I could do the following, it would be quicker by far than any ways of achieving my goal without setting the private property value.
Upvotes: 2
Views: 5201
Reputation: 2046
You could always utilize the "new" keyword, but the inherited method would be ignored if the class is cast back to its base object
public InheritingClass : BaseClass
{
public InheritingClass()
{
Values = new InhertingList<string>(); ?
}
public new List<string> Values { get; private set; }
}
To access private fields you can use Reflection, but since the field is private I'm not certain how the inheriting class would benefit from changing a private field type.
public InheritingClass : BaseClass
{
private static FieldInfo _valueField = typeof(BaseClass).GetField("_values", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
public InheritingClass()
{
_valueField.SetValue(this, new InhertingList<string>());
}
}
http://msdn.microsoft.com/en-us/library/6z33zd7h(v=vs.110).aspx
Upvotes: 0
Reputation: 715
If you really need to set the value, you can use reflection. But that's no good coding style and may be slow.
Edit: It might be possible to disassemble your BaseClass and change its implementation. Bun then you might have to disassemble the whole library.
Perhaps you can provide some more details on your problem?
Upvotes: 2
Reputation: 564451
Keeping it private, by definition, is meant to prevent this exact scenario.
The best option would be to implement a protected setter:
public class BaseClass
{
public Values {
get { return _values; }
protected set { _values = value; }
}
}
This way, your InheritingClass has access to the setter, and can do:
this.Values = new InhertingList<string>();
But since you can't change the base class, it is, technically, possible to do this via reflection (in a full trust scenario). I don't recommend this approach, though:
FieldInfo field = typeof(BaseClass).GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic );
field.SetValue(this, this.Values = new InhertingList<string>() );
The danger of doing what you are attempting, btw, is that you're going to change the implementation defined by the BaseClass to something that you're providing. It's very easy to introduce subtle bugs, since you're (purposefully) "breaking" the implementation details in the base class.
I'd try to rethink your algorithm, and see if there's another way around this issue.
Upvotes: 8
Reputation: 29956
You can't set the private property. You will either have to inherit from another base class or create your own base class that provides the behaviour.
Of course, depending on the level of trust your application is running under, you may be able to set the private variable via reflection but that would really be a hack to get around what is actual a problem in the design.
Upvotes: 1
Reputation: 3213
Usually, when you don't have a property with an accessible setter provided for a field, it means that you should not modify that field from anywhere but the BaseClass - if the creator of the BaseClass class would have wanted you to be able to modify that field, he'd have exposed a property with a protected setter or something like that. So generally it's not recommended to hack it.
You could certainly do it by reflection though, providing you know the name of the private field - I don't think it is possible to extract the body of the property.
As for the other answers: he wrote "I've got a base class from an outside library that I can't modify".
Upvotes: 1
Reputation: 320
Normally, when fields don't have mutator methods, you'd use the constructor of the class to instantiate the object (and it's relevant fields).
BaseClass base = new BaseClass(List<string> yourList);
Upvotes: 0
Reputation: 10582
No, there is no way to do what you're looking for. Private variables are meant to be private - namely, they can't be seen or altered by any code.
Upvotes: 0