0
votes

Since properties can have public and private getters / setters, is there still a use for fields? Any behaviour you get from using fields can be gotten by designing the get / set blocks of properties to use the invisible variable that the compiler uses, and leaving the fields out alltogether?

5

5 Answers

3
votes

no, auto-implemented props do NOT remove the need for backing fields. Sometimes, a property getter/setter does more work then just hold a value. There are many cases where you may want a field. a very good example is when implementing INotifyPropertyChanged for binding.

like so:

class someClass : INotifyPropertyChanged
{
// details omitted.....

    private int _myInt
    public int myInt { get { return _myInt; }
                       set { if ( value == _myInt ) return;
                             _myInt = value;
                             RaiseNotify("myIng");
                           }}
}

this would be impossible without backing fields.

0
votes

Auto-implemented properties remove the need for fields in simple cases.

However, if you want to add any kind of logic or validation or events to the property setter, you'll still need a field.

0
votes

In most cases, you can use autogen getters and setters instead of a field, but there is a subtle difference: A getter and a setter are a function call, even if inlined - thus a backing variable is always adresses as if it were volatile.

0
votes

While it's possible to get a value of a field, and set a field, fields allow one to do a couple things which cannot be done with properties:

  1. It is possible to modify the value of a field in such a way that the new value will depend upon the old value at the exact moment of modification. This has different semantics from reading the property, computing a new value, and writing it back.
  2. It is possible to pass a field by reference to methods which are then free to perform whatever sequence of reads and writes they see fit, with such reads or writes happening "live". Again this has different semantics from passing a copy of the property to a method, receiving a modified copy back from the method, and storing that modified copy back to the original.

If one wanted to expose a property in a way that would make it possible to do 'field-like' things with it, but without exposing the actual field, one could have a family of generic UseProperty methods, declared as:

delegate TResult; FuncRef<T1, TResult>(ref T1);
ResultType UseProperty<ResultType>
  (FuncRef func)
  {return func(_field);}
delegate TResult; FuncRef(ref T1 p1, ref T2 p2>
ResultType UseProperty<ResultType, T1>
  (FuncRef<propertyType, T1, ResultType> func, ref T1 p1)
  {return func(_field, p1);}
delegate TResult; FuncRef(ref T1 p2, ref T2 p2, ref T3 p3>
ResultType UseProperty<ResultType, T1, T2>
  (FuncRef<propertyType, T1, T2, ResultType> func, ref T1 p1, ref T2 p2)
  {return func(_field, p1, p2);}

Unfortunately, there's no nice way to declare a family of such functions in C# or vb (i.e. a 'universal' function which would accept any number of 'ref' parameters, and make them available to the called code). Too bad, since otherwise, with some language support, such an approach could provide a very nice paradigm for controlling access to information (i.e. it could prepare to have certain information modified, allow general code to modify the information, and then act upon the modified information, without having to create any new object instances).

0
votes

The primary reason people use properties for protected and public fields is so you can add behavior without breaking binary compatibility. This means code that uses (calls, subclasses, etc.) your class does not need to be recompiled.

There's no real need to use properties for private members with no behavior. In that case, you can use a field. If you later need to add behavior (making it a property), you will be recompiling that class anyway.

Fields do perform better (though it depends on which version of the JIT you have), so they should be used unless there's a reason not to.

EDIT:

Just to avoid confusion:

Field:

private SomeType fieldName;

Auto-property:

private SomeType fieldName { get; set; }