Does having a public field with private accessors make sense? - c#

I have a class called GestorePersonale which holds a list of instances of another class:
public List<Dipendente> Dipendenti
{
get;
private set;
}
I want to keep this list modifiable only from the methods the class exposes, and not directly. I noticed that with the code above, one could just do var gp = new GestorePersonale();
gp.Dipendenti.Add( new Dipendente( ... ) );
and be able to perform any other kind of action on the List<Dipendente> itself.
I considered converting the first code snippet to
private List dipendenti;
but I could find a few downsides to that:
This would break the personal rule of mine to try to always use the public fields over the private ones from inside the class's methods whenever possible (even though I'm not sure if it is good practice to do so, so any clarification would be welcome);This would impair any external entities' ability to access the contents of the list for reading purposes only, like, say, to execute a LINQ query over the contents of the list.
What would be the best way to solve this situation?

You can wrap the list in a ReadOnlyCollection<T> and expose that:
private List<Dipendente> dipendenti;
private ReadOnlyCollection<Dipendente> readOnlyDipendenti;
public GestorePersonale()
{
dipendenti = new List<Dipendente>();
readOnlyDipendenti = new ReadOnlyCollection<Dipendente>(dipendenti);
}
public ReadOnlyCollection<Dipendente> Dipendenti
{
get { return readOnlyDipendenti; }
}
Internally, you have access to dipendenti and can add/remove items. External entities have access only to the ReadOnlyCollection<T> that wraps the list, so they can only read, but not add/remove items.

I would agree with dtb that ReadOnlyCollections is the way to go. However, you can return it from the property getter (using AsReadOnly) and drop the method.
private List<Dipendente> dipendenti = new List<Dipendente>();
public ReadOnlyCollection<Dipendente> ReadOnlyDipendenti
{
get
{
return dipendenti.AsReadOnly();
}
}

there are a couple of things you can do:
you use ReadOnlyCollection
you can return an IEnumerable<_type>
you can wrap the list in another class
you can roll your own collection class, implementing the appropriate interface
the method you use depends on the functionality you need and what you want/need to expose to the user of your class

What you have is a public property with a private accessor. It is very useful. It allows an instance to expose a value that is controlled (set) by the instance itself, e.g. a state.
For example, take a collection with a Count property. It makes no sense for it have a public accessor. An implementation could be to update the property (internally) when the collection is changed (to avoid having to count it each time).

Do a setter method or wrap the field in another class. This is a classic collection set and collection.add problem.

Related

IEnumerable versus List in a concrete class implementation

I am writing a class library for financial modeling.
I want to define the models using interfaces to create abstraction for testing, and the possible later addition of new concrete classes.
I am struggling on how to define lists of things, so I can later add to those lists in the concrete class.
For example, if I define an interface as having a list of expenses in my Model called
IEnumerable Expenses {get; set;}
and later want to create a concrete class called ABCModel with a list of concrete XYZExpense in it, what would be the best way to implement the lists so I can easily add more items to the list?
I cannot cast the List as a IEnumerable.
So for example:
public interface IFinancialModel
{
IEnumerable<IExpense> Expenses { get; }
IEnumerable<IRevenue> Revenue { get; }
IEnumerable<IAsset> Assets { get; }
IEnumerable<ILiability> Liabilities { get; }
}
I need a concrete class called public class FinancialModel : IFinancialModel
and be able to add concrete items.
Should I create 'Add' methods of my own? Ideally I would like to leverage built in List functionality and not reinvent the wheel.
It depends on what you actually want to do. Having List or IList properties is not recommended, because you can do everything with it (like Clear, Add and so on) without the owning class know about it. This is not good for encapsulation. You wouldn't be able to do something on change (like setting a dirty flag, fire changed events or do validation).
IEnumerable is a good choice.
You may add setters, but you shouldn't take the value that is set to the property by reference. It could be anything, like a Linq query or even a database query, which you don't want to reference to. You only want the items. (Also consider that the reference to the collection which comes from the outside can be assigned to other instances, which results in very bad side effects when it is changed there but shouldn't be changed here.)
// example implementation with a setter
private List<IExpense> expenses
public IEnumerable<IExpense> Expenses
{
get { return expenses; }
set { expenses = value.ToList(); }
}
Alternatively you may implement your own Add, AddRange, Remove or Clear etc. methods. However, if the main use case is to set all items in one go, you can only have a SetExpenses method, which is the same as the setter on the property I showed before. You may consider to keep it as an array internally.
What you are looking for is IList<T>. This is an interface that allows you to expose the lists while hiding the actual list implementation. For ex:
interface IFinancialModel {
IList<IExpense> Expenses { get; }
}
Then implement with a list that satisfies your needs. For example:
class FinancialModel : IFinancialModel {
private IList<IExpense> _expenses = new List<IExpense>();
IList<IExpense> Expenses { get { return _expenses; } }
}
I agree with #Stefan though, exposing a list breaks encapsulation and should generally be avoided.

Accesing class methods/variables from another class

stupid question really, I have private variables, which I encapsulated and now I want to access them from another class.
I also have a list in one class and want a lot of classes to access that list (list of objects called fields) (creating a simple farm simulator).
So how can I access them from another class?
I know I can make an instace of a class, but with lists, will that mean that my list won't be the same when I create instances of the class in the classes that I want to access the list in?
I don't think I can use Namespace.class.Something since their not static, or can I?
Maybe use inheritance for list or is that not going to work?
Please help, realllyyy would appreciate any help!!
*thank you in advance
You cannot access a private member from within another class (except the member is a member of a nested class). So the proposal from Konrad Kokosa to use Properties instead was absolutely fine as they should be used to control access from outside the actual class. Having said this you may either turn the access-modifier for that property to public or derive from that class (however, you have to use protected access for the property then).
MyClass {
public static List<Field> MyList {get;set;}
}
AnotherClass {
AnotherClass() {
MyClass.MyList = // whatever
// or also possible
MyClass.MyList.Add(/*new Item*/);
}
}
Private members cannot be used outside of the class (unless you use reflection, which I would not recommend). If you want the members to be available to outside classes, you have to make them "public". If you want your members to be available to all derived classes only, use "protected".
If you want to access the same list from all o the other classes, you should declare it as static:
private static List<Field> s_fields = new List<Field>();
public static List<Field> Fields { get { return s_fields; } }

Setting Values on a derived class from the base class constructor using Reflection

I have two classes like this:
public abstract class MyBase
{
protected MyBase(){
Initialize();
}
protected IDictionary<string,string> _data;
private void Initialize() {
// Use Reflection to get all properties
// of the derived class (e.g., call new MyDerived() then
// I want to know the names "Hello" and "ID" here
var data = GetDataFromBackend(propertyNamesFromDerived);
_data = data;
}
}
public class MyConcrete : MyBase
{
public MyConcrete(){
// Possibly use Reflection here
Hello = _data["Hello"];
ID = new Guid(data["ID"]);
}
public string Hello {get;set;}
public Guid ID {get; set;}
}
As you see, I want the constructor of my base class to know about the properties of the derived class I'm instantiating.
Now, this seems like a huge and big code smell, so let me give some more background about my intentions, maybe there is a better way.
I have a backend system that stores Key/Value Pairs, essentially a Dictionary<string,string>. I want to abstract away working with this backend system in a way where people can create classes whose properties are Keys into the backend system. When they construct this object, it will automatically load the data from that system and initialize all the variables to it.
In other words, I've just reinvented serialization, except that I don't control the backend system and just rather make working with it really painless. I don't want callers to have to call Initialize() after constructing the object, because in 100% of the cases you have to initalize it after constructing.
I don't want to move the initialize code into the Derived Classes, except for string-to-business-object conversion.
Would I have to use a Factory? Or is it considered safe to look at the property names of a derived class in a base constructor? (Don't care about their values and that they aren't initialized, just need the names).
Or is there a better way altogether to provide a facade between a Dictionary of strings and a concrete business object?
Edit: This is .net 3.5, so no System.Dynamic which would make this trivial :(
Edit 2: After looking at the Answers and thinking through this some more, I guess my question really boils down to this now: Is calling GetType().GetProperties() from a base constructor in order to get the Names of Properties and if they are decorated with a certain Attribute safe?
Wait, let's stop here for a second and do this properly. It shouldn't be MyBase's responsibility to do this.
So you write a class that manages getting stuff out of the backend for you, and you write a method on that class that is something like
T Get<T>() where T : new()
and you make Get responsible for reading the dictionary out of the backend and using reflection to populate an instance of T. Thus, you say
var concrete = foo.Get<MyConcrete>();
This isn't hard, and it's the right way to do it.
Incidentally, the code for Get is going to look something like
T t = new T();
var properties = typeof(T).GetProperties();
foreach(var property in properties) {
property.SetValue(t, dictionary[property.Name], null);
}
return t;
where dictionary is your loaded up key/value pairs. It turns out there are more optimal ways to do this, but unless it's a bottleneck I wouldn't worry about it.
The better way to do this would be to make the classes use the dictionary directly:
public string Hello {
get { return (string)base.data["Hello"]; }
set { base.data["Hello"] = value; }
}
You may want to call TryGetValue in the getter so that you can return a default value if the key isn't there. (You should probably do that in a separate method in the base class)
You can make a code snippet to make the properties easier to create.
If you don't want to do it this way, you can call GetType().GetProperties() to get PropertyInfo objects for the properties in your class, then call SetValue(this, value).
This will be slow; there are various tricks you can use to speed it up using expression trees, CreateDelegate, or IL generation.
Maybe try the Template method pattern
Have you considered using an ExpandoObject? With it you can dynamically add properties and inspect them (when serializing for example).
I'm not sure if it's what you really should do, but here's what you asked for (put this in Initialize, and you'll get a list of the derived property names):
var derivedProps = this.GetType().GetProperties();
var propNames = new List<string>(derivedProps.Select(x => x.Name));
From there, using the PropertyInfos in derivedProps, you can set the properties.
You can't really safely do anything to those properties in the base-class constructor anyway as some derived constructor may reset them anyway. You're much better off doing a two-phased load (e.g. call Initialize explicitly)

Are there any reasons to use private properties in C#?

I just realized that the C# property construct can also be used with a private access modifier:
private string Password { get; set; }
Although this is technically interesting, I can't imagine when I would use it since a private field involves even less ceremony:
private string _password;
and I can't imagine when I would ever need to be able to internally get but not set or set but not get a private field:
private string Password { get; }
or
private string Password { set; }
but perhaps there is a use case with nested / inherited classes or perhaps where a get/set might contain logic instead of just giving back the value of the property, although I would tend to keep properties strictly simple and let explicit methods do any logic, e.g. GetEncodedPassword().
Does anyone use private properties in C# for any reason or is it just one of those technically-possible-yet-rarely-used-in-actual-code constructs?
Addendum
Nice answers, reading through them I culled these uses for private properties:
when private fields need to be lazily loaded
when private fields need extra logic or are calculated values
since private fields can be difficult to debug
in order to "present a contract to yourself"
to internally convert/simplify an exposed property as part of serialization
wrapping global variables to be used inside your class
I use them if I need to cache a value and want to lazy load it.
private string _password;
private string Password
{
get
{
if (_password == null)
{
_password = CallExpensiveOperation();
}
return _password;
}
}
The primary usage of this in my code is lazy initialization, as others have mentioned.
Another reason for private properties over fields is that private properties are much, much easier to debug than private fields. I frequently want to know things like "this field is getting set unexpectedly; who is the first caller that sets this field?" and it is way easier if you can just put a breakpoint on the setter and hit go. You can put logging in there. You can put performance metrics in there. You can put in consistency checks that run in the debug build.
Basically, it comes down to : code is far more powerful than data. Any technique that lets me write the code I need is a good one. Fields don't let you write code in them, properties do.
perhaps there is a use case with nested / inherited classes or perhaps where a get/set might contain logic instead of just giving back the value of the property
I personally use this even when I don't need logic on the getter or setter of a property. Using a property, even a private one, does help future-proof your code so that you can add the logic to a getter later, if required.
If I feel that a property may eventually require extra logic, I will sometimes wrap it into a private property instead of using a field, just so I don't have to change my code later.
In a semi-related case (though different than your question), I very frequently use the private setters on public properties:
public string Password
{
get;
private set;
}
This gives you a public getter, but keeps the setter private.
One good usage for private get only properties are calculated values. Several times I've had properties which are private readonly and just do a calculation over other fields in my type. It's not worthy of a method and not interesting to other classes so private property it is.
Lazy initialization is one place where they can be neat, e.g.
private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */);
private MyType MyType { get { return this.mytype.Value; } }
// In C#6, you replace the last line with: private MyType MyType => myType.Value;
Then you can write: this.MyType everywhere rather than this.mytype.Value and encapsulate the fact that it is lazily instantiated in a single place.
One thing that's a shame is that C# doesn't support scoping the backing field to the property (i.e. declaring it inside the property definition) to hide it completely and ensure that it can only ever be accessed via the property.
The only one usage that I can think of
private bool IsPasswordSet
{
get
{
return !String.IsNullOrEmpty(_password);
}
}
Properties and fields are not one to one. A property is about the interface of a class (whether talking about its public or internal interface), while a field is about the class's implementation. Properties should not be seen as a way to just expose fields, they should be seen as a way to expose the intent and purpose of the class.
Just like you use properties to present a contract to your consumers on what constitutes your class, you can also present a contract to yourself for very similar reasons. So yes, I do use private properties when it makes sense. Sometimes a private property can hide away implementation details like lazy loading, the fact that a property is really a conglomeration of several fields and aspects, or that a property needs to be virtually instantiated with each call (think DateTime.Now). There are definitely times when it makes sense to enforce this even on yourself in the backend of the class.
I use them in serialization, with things like DataContractSerializer or protobuf-net which support this usage (XmlSerializer doesn't). It is useful if you need to simplify an object as part of serialization:
public SomeComplexType SomeProp { get;set;}
[DataMember(Order=1)]
private int SomePropProxy {
get { return SomeProp.ToInt32(); }
set { SomeProp = SomeComplexType.FromInt32(value); }
}
I use private properties to reduce code for accessing sub properties which often to use.
private double MonitorResolution
{
get { return this.Computer.Accesories.Monitor.Settings.Resolution; }
}
It is useful if there are many sub properties.
One thing I do all the time is store "global" variables/cache into HttpContext.Current
private static string SomeValue{
get{
if(HttpContext.Current.Items["MyClass:SomeValue"]==null){
HttpContext.Current.Items["MyClass:SomeValue"]="";
}
return HttpContext.Current.Items["MyClass:SomeValue"];
}
set{
HttpContext.Current.Items["MyClass:SomeValue"]=value;
}
}
I use them every now and then. They can make it easier to debug things when you can easily put in a breakpoint in the property or you can add a logging statement etc.
Can be also be useful if you later need to change the type of your data in some way or if you need to use reflection.
I know this question is very old but the information below was not in any of the current answers.
I can't imagine when I would ever need to be able to internally get but not set
If you are injecting your dependencies you may well want to have a Getter on a Property and not a setter as this would denote a readonly Property. In other words the Property can only be set in the constructor and cannot be changed by any other code within the class.
Also Visual Studio Professional will give information about a Property and not a field making it easier to see what your field is being used.
It is a common practice to only modify members with get/set methods, even private ones. Now, the logic behind this is so you know your get/set always behave in a particular way (for instance, firing off events) which doesn't seem to make sense since those won't be included in the property scheme... but old habits die hard.
It makes perfect sense when there is logic associated with the property set or get (think lazy initialization) and the property is used in a few places in the class.
If it's just a straight backing field? Nothing comes to mind as a good reason.
Well, as no one mentioned you can use it to validate data or to lock variables.
Validation
string _password;
string Password
{
get { return _password; }
set
{
// Validation logic.
if (value.Length < 8)
{
throw new Exception("Password too short!");
}
_password = value;
}
}
Locking
object _lock = new object();
object _lockedReference;
object LockedReference
{
get
{
lock (_lock)
{
return _lockedReference;
}
}
set
{
lock (_lock)
{
_lockedReference = value;
}
}
}
Note: When locking a reference you do not lock access to members of the referenced object.
Lazy reference: When lazy loading you may end up needing to do it async for which nowadays there is AsyncLazy. If you are on older versions than of the Visual Studio SDK 2015 or not using it you can also use AsyncEx's AsyncLazy.
One more usage would be to do some extra operations when setting value.
It happens in WPF in my case, when I display some info based on private object (which doesn't implement INotifyPropertyChanged):
private MyAggregateClass _mac;
private MyAggregateClass Mac
{
get => _mac;
set
{
if(value == _mac) return;
_mac = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DisplayInfo)));
}
}
public string DisplayInfo => _mac.SomeStringInformationToDisplayOnUI;
One could also have some private method, such as
private void SetMac(MyAggregateClass newValue)
to do that.
Some more exotic uses of explicit fields include:
you need to use ref or out with the value - perhaps because it is an Interlocked counter
it is intended to represent fundamental layout for example on a struct with explicit layout (perhaps to map to a C++ dump, or unsafe code)
historically the type has been used with BinaryFormatter with automatic field handling (changing to auto-props changes the names and thus breaks the serializer)
Various answers have mentioned using properties to implement a lazy member. And this answer discussed using properties to make live aliases. I just wanted to point out that those two concepts sometimes go together.
When using a property to make an alias of another object's public property, the laziness of that property is preserved:
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private IDbConnection Conn => foo.bar.LazyDbConnection;
On the other hand, retrieving that property in the constructor would negate the lazy aspect:
Conn = foo.bar.LazyDbConnection;
Looking into the guideline (Properties (C# Programming Guide)) it seems no one expects to use properties as private members.
Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.
In any case it can be interchanged by one or two methods and vice versa.
So the reason can be to spare parentheses on getting and get field syntax on setting.

How to expose a collection property? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Every time I create an object that has a collection property I go back and forth on the best way to do it?
public property with a getter that
returns a reference to private variable
explicit get_ObjList and set_ObjList
methods that return and create new or cloned
objects every time
explicit get_ObjList that returns an
IEnumerator and a set_ObjList that
takes IEnumerator
Does it make a difference if the collection is an array (i.e., objList.Clone()) versus a List?
If returning the actual collection as a reference is so bad because it creates dependencies, then why return any property as a reference? Anytime you expose an child object as a reference the internals of that child can be changed without the parent "knowing" unless the child has a property changed event. Is there a risk for memory leaks?
And, don't options 2 and 3 break serialization? Is this a catch 22 or do you have to implement custom serialization anytime you have a collection property?
The generic ReadOnlyCollection seems like a nice compromise for general use. It wraps an IList and restricts access to it. Maybe this helps with memory leaks and serialization. However it still has enumeration concerns
Maybe it just depends. If you don't care that the collection is modified, then just expose it as a public accessor over a private variable per #1. If you don't want other programs to modify the collection then #2 and/or #3 is better.
Implicit in the question is why should one method be used over another and what are the ramifications on security, memory, serialization, etc.?
How you expose a collection depends entirely on how users are intended to interact with it.
1) If users will be adding and removing items from an object's collection, then a simple get-only collection property is best (option #1 from the original question):
private readonly Collection<T> myCollection_ = new ...;
public Collection<T> MyCollection {
get { return this.myCollection_; }
}
This strategy is used for the Items collections on the WindowsForms and WPF ItemsControl controls, where users add and remove items they want the control to display. These controls publish the actual collection and use callbacks or event listeners to keep track of items.
WPF also exposes some settable collections to allow users to display a collection of items they control, such as the ItemsSource property on ItemsControl (option #3 from the original question). However, this is not a common use case.
2) If users will only be reading data maintained by the object, then you can use a readonly collection, as Quibblesome suggested:
private readonly List<T> myPrivateCollection_ = new ...;
private ReadOnlyCollection<T> myPrivateCollectionView_;
public ReadOnlyCollection<T> MyCollection {
get {
if( this.myPrivateCollectionView_ == null ) { /* lazily initialize view */ }
return this.myPrivateCollectionView_;
}
}
Note that ReadOnlyCollection<T> provides a live view of the underlying collection, so you only need to create the view once.
If the internal collection does not implement IList<T>, or if you want to restrict access to more advanced users, you can instead wrap access to the collection through an enumerator:
public IEnumerable<T> MyCollection {
get {
foreach( T item in this.myPrivateCollection_ )
yield return item;
}
}
This approach is simple to implement and also provides access to all the members without exposing the internal collection. However, it does require that the collection remain unmodfied, as the BCL collection classes will throw an exception if you try to enumerate a collection after it has been modified. If the underlying collection is likely to change, you can either create a light wrapper that will enumerate the collection safely, or return a copy of the collection.
3) Finally, if you need to expose arrays rather than higher-level collections, then you should return a copy of the array to prevent users from modifying it (option #2 from the orginal question):
private T[] myArray_;
public T[] GetMyArray( ) {
T[] copy = new T[this.myArray_.Length];
this.myArray_.CopyTo( copy, 0 );
return copy;
// Note: if you are using LINQ, calling the 'ToArray( )'
// extension method will create a copy for you.
}
You should not expose the underlying array through a property, as you will not be able to tell when users modify it. To allow modifying the array, you can either add a corresponding SetMyArray( T[] array ) method, or use a custom indexer:
public T this[int index] {
get { return this.myArray_[index]; }
set {
// TODO: validate new value; raise change event; etc.
this.myArray_[index] = value;
}
}
(of course, by implementing a custom indexer, you will be duplicating the work of the BCL classes :)
I usually go for this, a public getter that returns System.Collections.ObjectModel.ReadOnlyCollection:
public ReadOnlyCollection<SomeClass> Collection
{
get
{
return new ReadOnlyCollection<SomeClass>(myList);
}
}
And public methods on the object to modify the collection.
Clear();
Add(SomeClass class);
If the class is supposed to be a repository for other people to mess with then I just expose the private variable as per method #1 as it saves writing your own API, but I tend to shy away from that in production code.
ReadOnlyCollection still has the disadvantage that the consumer can't be sure that the original collection won't be changed at an inopportune time. Instead you can use Immutable Collections. If you need to do a change then instead changing the original you are being given a modified copy. The way it is implemented it is competitive with the performance of the mutable collections. Or even better if you don't have to copy the original several times to make a number of different (incompatible) changes afterwards to each copy.
I recommend to use the new IReadOnlyList<T> and IReadOnlyCollection<T> Interfaces to expose a collection (requires .NET 4.5).
Example:
public class AddressBook
{
private readonly List<Contact> contacts;
public AddressBook()
{
this.contacts = new List<Contact>();
}
public IReadOnlyList<Contact> Contacts { get { return contacts; } }
public void AddContact(Contact contact)
{
contacts.Add(contact);
}
public void RemoveContact(Contact contact)
{
contacts.Remove(contact);
}
}
If you need to guarantee that the collection can not be manipulated from outside then consider ReadOnlyCollection<T> or the new Immutable collections.
Avoid using the interface IEnumerable<T> to expose a collection.
This interface does not define any guarantee that multiple enumerations perform well. If the IEnumerable represents a query then every enumeration execute the query again. Developers that get an instance of IEnumerable do not know if it represents a collection or a query.
More about this topic can be read on this Wiki page.
If you're simply looking to expose a collection on your instance, then using a getter/setter to a private member variable seems like the most sensible solution to me (your first proposed option).
Why do you suggest using ReadOnlyCollection(T) is a compromise? If you still need to get change notifications made on the original wrapped IList you could also use a ReadOnlyObservableCollection(T) to wrap your collection. Would this be less of a compromise in your scenario?
I'm a java developer but I think this is the same for c#.
I never expose a private collection property because other parts of the program can change it without parent noticing, so that in the getter method I return an array with the objects of the collection and in the setter method I call a clearAll() over the collection and then an addAll()

Categories

Resources