Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid public access to private fields?

Tags:

For example let's declare:

private readonly List<string> _strings = new List<string>(); public IEnumerable<string> Strings {     get     {         return _strings;     } } 

And now we can do the following:

((List<string>) obj.Strings).Add("Hacked"); 

So we're really not hiding the List from usage but only hide it behind interface. How to hide the list in such example without copying _strings in the new collection to restrict modification of the list?

like image 732
Sergey Metlov Avatar asked May 07 '13 15:05

Sergey Metlov


People also ask

Can Super access private members?

No. Private variables are only accessible to the class members where it belongs. protected variables can be accessed from base class.

How do you access a private field using a reflection?

If we want to access Private Field and method using Reflection we just need to call setAccessible(true) on the field or method object which you want to access. Class. getDeclaredField(String fieldName) or Class. getDeclaredFields() can be used to get private fields.

Can we use super keyword in private method in Java?

Private methods of the super-class cannot be called. Only public and protected methods can be called by the super keyword. It is also used by class constructors to invoke constructors of its parent class. Super keyword are not used in static Method.

Which methods can access to private attributes of a class?

Answer: Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself. Private access modifier is more secure and restrictive access level, whereas class and interfaces cannot be private.


1 Answers

Plenty of ways.

The most naive approach would be to always copy the private field:

return _strings.ToList(); 

But that's not generally necessary. It would make sense, though, if:

  1. You happen to know that calling code will generally want a List<T> anyway, so you might as well give one back (without exposing the original).
  2. It's important for the exposed object to hold the original values even if the original collection is subsequently changed.

Alternately, you could just expose a read-only wrapper:

return _strings.AsReadOnly(); 

This is more efficient than the first option but will expose changes made to the underlying collection.

These strategies could also be combined. If you need a copy of the original collection (so changes to the original have no effect) but also don't want the object returned to be mutable*, you could go with:

 // copy AND wrap return _strings.ToList().AsReadOnly(); 

You could also use yield:

foreach (string s in _strings) {     yield return s; } 

This is similar in efficiency and trade-offs to the first option, but with deferred execution.

Clearly, the key thing to consider here is how your method is actually going to be used and what functionality, exactly, you mean to be providing with this property.

* Though to be honest, I'm not sure why you'd care.

like image 56
Dan Tao Avatar answered Oct 21 '22 08:10

Dan Tao