From the point of view of runtime there is no difference, of course. A property is nothing more than a pair of two functions — a getter and a setter; moreover, these functions, formally speaking, are not at all obliged to read / establish any field of the object.
There is a difference in semantics. When we talk about an object, we mean an abstraction of something from the outside world. This sounds rather trivial, but this leads to non-trivial conclusions.
An object has data that it possesses, and a behavior . What is data is modeled by properties. What is behavior is modeled by methods. At the same time, it does not matter at all whether the object data is represented by a field, several fields, or is calculated on the fly at all — these are implementation details that are not interesting to anyone “outside”. This is one of the reasons why properties should be set out, not fields .
Let's say you have a dog. She has a coat color, a nickname, and she knows how to execute commands. Now let's look at the difference.
A nickname is a property of a dog: it is something that is an object (line) inherent in the dog itself. It can be installed (for example, the new owner of the dog can change the nickname), and read. Accordingly, it needs to be modeled by the property:
public string Name { get; set; }
The dog's coat color is also its property. But it is impossible to "install" it outside (let's digress from the possibility of repainting the dog: the color of the paint and the color of the coat are not the same). Therefore, it must be modeled with a property that is read-only:
private readonly Color color; public Color Color { get { return color; } }
(or for C # 6 that was released a couple of days ago, you can simply
public Color Color { get; }
since the value can be set in the constructor).
Now, the execution of the command. This is not a property of the dog itself, it is her behavior. Thus, it will be correct to model the execution of a command like this:
public void ExecuteCommand(DogCommand command) { ... }
Notice that the formal attributes (“I just get the value of the field!”) Are irrelevant. For example, if you have a team that is currently being executed by a dog, it is recorded in the inner field, and you want to be able to find out which command the dog is performing at the moment, it will be wrong to issue a command like this:
private DogCommand currentCommand = null; public DogCommand CurrentCommand { get { return currentCommand; } set { if (currentCommand != null) StopExecuting(); currentCommand = value; if (currentCommand != null) StartExecuting(); } }
because the team is not an inherent property of the dog itself, but only its behavior. For example, it would be correct to:
bool isExecutingCommand = false; DogCommand currentCommand = null; public void ExecuteCommand(DogCommand command) { if (isExecutingCommand) CancelCommand(); isExecutingCommand = true; currentCommand = command; StartCommand(command); } public DogCommand GetCurrentExecutingCommand() { return isExecutingCommand ? currentCommand : null; }