Other being able to sanity check values in a setter is there a more underlying reason to prefer properties to public variables?
-
Effectively a dupe of http://stackoverflow.com/questions/641619/when-should-you-use-a-field-rather-than-a-property and http://stackoverflow.com/questions/379041/what-is-the-best-practice-for-using-public-fields/379057 -- among others. – tvanfosson Apr 10 '09 at 10:52
8 Answers
We've had this subject before but I can't find anything now.
In brief: your needs might change: where there's no sanity check now, one might be required in the future. However, if you change your public fields to properties, this breaks binary compatiblity: every client who uses your code/library would have to re-compile.
This is bad because it potentially costs a lot of money.
Using properties from the beginning avoids this problem. This even counts for code that is not part of a library. Why? Because you never know: the code (even if highly domain-specific!) might prove useful so you want to refactor it to a library. This refactoring process is obviously made much easier if you are already using properties in place of public/protected fields.
Additionally, writing public properties is easy in C# 3.0 because you can just use the auto-implemented properties, saving you quite a bit of code:
public DataType MyProperty { get; set; }
Will implement the necessary backing field and getter/setter code for you.
I will add a personal note: .NET's behaviour in this regard is somewhat lazy. The compiler could just change public fields to properties on the fly, thus avoiding the problem. VB6 already did this for COM-exposed classes and I see absolutely no reason for VB.NET and C# not to do the same. Perhaps someone on the compiler teams (Jared?) could comment on this.

- 530,221
- 131
- 937
- 1,214
-
3Ignoring the should question, there are many reasons why the Compiler cannot do this. There are 2 reasons that come immediately to mind. 1) names and 2) calling a property is not the same as accessing a field (performance, ref and out). Unfortunately there's not enough space here to truly comment – JaredPar Apr 10 '09 at 13:26
-
4(cont) and the thread is closed. But the short version is the user is asking for one item and you're giving them a non-equal replacement. Users are often unhappy when you do that. – JaredPar Apr 10 '09 at 13:27
-
1I thought the same thing, but as always, structs cause problems: v.S.M = 5 assigns 5 to the member M of struct S. If S is a field, there's no problem. If it's a property, this would only modify M in a temporary copy of S returned from the property getter. Mutable structs are the root of much evil! – Daniel Earwicker Apr 10 '09 at 13:41
-
"if you change your public fields to properties, this breaks binary compatiblity: every client who uses your code/library would have to re-compile"... This is often quoted, but seems wrongheaded to me. Can you EVER think of a situation where a third party has shipped you a vNew of some assembly, and you haven't had to recompile anyway due to method/class/namespaces changes? Typically you'll *want* to be recompiling anyway to use some of the things in vNew. – Orion Edwards Aug 04 '17 at 03:04
-
@OrionEdwards Can I think of situations? Sure: virtually every operating system or core component update. Those updates *never* break binary compatibility, because otherwise all hell’d break loose. Have you ever recompiled software after a .NET/Java/… update? You might not even realise how frequent these updates are because everything just continues working. – Konrad Rudolph Aug 04 '17 at 09:43
-
@konradrudolph sure, but I’m not writing the dotnet core framework. Most of the time, I (and the majority of other developers, I bet) am not even writing libraries or shared code, I’m writing application code that sits at the end of th dependency chain. – Orion Edwards Aug 05 '17 at 18:56
-
@OrionEdwards Honestly, more people should be writing libraries. In fact, with well-written code, *most* code should reside in reusable libraries, and relatively little in the front-end application. Admittedly I’m also guilty of winging it but that doesn’t make it good software engineering. If you use libraries rigorously, stable interfaces become a huge boon. – Konrad Rudolph Aug 07 '17 at 09:49
In a nutshell:
- You can control acces (readonly,
writeonly, read/write) - You can validate values when setting a property (check for null etc)
- You can do additional processing, such as lazy initialization
- You can change the underlying implementation. For example, a property may be backed by a member variable now, but you can change it to be backed by a DB row without breaking any user code.

- 60,939
- 11
- 97
- 136
Jeff Atwood has blogged about it:
There are valid reasons to make a trivial property, exactly as depicted above:
- Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
- You can't databind against a variable.
- Changing a variable to a property is a breaking change.
It's a shame there's so much meaningless friction between variables and properties; most of the time they do the exact same thing. Kevin Dente proposed a bit of new syntax that would give us the best of both worlds:
public property int Name;
However, if the distinction between variable and property is such an ongoing problem, I wonder if a more radical solution is in order. Couldn't we ditch variables entirely in favor of properties? Don't properties do exactly the same thing as variables, but with better granular control over visibility?

- 1
- 1

- 13,347
- 10
- 48
- 61
Changing a field to a property in the future is considered a breaking change. Fields are considered implementation details of classes and exposing them publicly breaks encapsulation.

- 414,610
- 91
- 852
- 789
-
It is only a breaking change if the calling code can not be recompiled, most of the time you own the caller code and it is compiled by the same build system. Hence this is not a problem for most peole out side of the .NET framework team. – Ian Ringrose Apr 10 '09 at 11:05
-
@Ian Ringrose: It's not completely source compatible either. For example, your code might do a `ref obj.MyField`. You cannot change `MyField` to `MyProperty` without changing the source. – Mehrdad Afshari Apr 10 '09 at 11:10
-
@Ian: It is a breaking change - http://msdn.microsoft.com/en-us/library/ms182141(VS.80).aspx – Cerebrus Apr 10 '09 at 11:12
You can also protect write access and allow read access with a property:
public int Version { get; private set; }
-
1This actually doesn't compile. I think what you mean is: `public int Version { get; private set; }` – Ian R. O'Brien May 21 '14 at 14:01
If you work in a closed environment -- you dont develop a SDK, all classes are used within a same project framework -- there is no difference.
The usual argument is that "in the future you may need to do some check on the values, so it is easier with properties". I dont buy it at all.
Using public fields is more readable, less decoration and easier to use.

- 940
- 1
- 10
- 19
Yes.
Consider a public varibale which now holds a string, you can simply set it. However, if you decide that that public variable should hold an object which should be initialized with a string then you would have to change all your code using your original object. But if you would have used setter you would only have to change the setter to initialize the object with the provided string.

- 31,965
- 17
- 72
- 98