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

Viewed 92580

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
19 Answers

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.

PorpField

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)

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.

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;
Related