Private Properties vs Fields in C# – Usage Guide

cfieldsproperties

A lot of people follow the following paradigm:

are always private.

are only used to expose fields, thus should only be public.
There are plenty of exceptions to this rule (lazy loading, for example).

With auto-properties, I've found it possible to never use fields. If I need my fields to be very basic, I just use auto-properties

private int? ThisIsMoreOrLessAField { get; set; } // Actually a private property

What is generally preferred? Some people like fields because if anyone ever decides to change a field and make it public, it's very obviously bad code and easy to recognize in code-review. It's also easy to look at fields and recognized that it's private to the class. If your properties can be private, that breaks that paradigm. You have to do further inspection to determine if it's public or private.

I'm having a hard time convincing myself either way.

Best Answer

As Robert Harvey said, what is generally preferred is to use fields for what they are designed for (private state), and to use properties for what they are designed for (exposing a public API).

The two exceptions I find in practice are:

  • Derived fields, where you do a little math on get and set. Sure, you could use get and set functions, but if I wanted to write Java I'd use Java.
  • Situations where you need to keep track of or fire events when your fields are modified. A simple example is logging when a field is changed or counting when something is accessed. I'm guessing that doesn't happen often in line-of-business type apps, but it can be common if you are doing something such as talking to a hardware device where you hide a lot of the details behind the interface, but need to still keep track of those fields over time for debugging.

Notice in those examples something else happens besides a get or set when the properties are used. Properties in C# are basically snazzy syntax which wraps getVar() and setVar() as seen in Java and COM. In C#, they provide the means to introduce some logic when the properties are used, but to otherwise be treated as an ordinary variable.

If you just have a variable with no logic on set or get, use a field.