42

Possible Duplicates:
Should I use public properties and private fields or public fields for data?
Difference between Automatic Properties and public field in C# 3.0

People seem to dogmatically insist on the use of public properties over fields but why is it so ultra-important in the case of simple properties?

How is

public int Foo { get; set; }

so incredibly different than

public int Foo;

?

Off the top of my head I can think of few practical differences between the two:

  • Accessing the member using reflection (rare, and most decent reflective algorithms will account for the difference)
  • The second entry allows you to use the field as a valid parameter for ref and out parameters, which would seem to be an advantage to using the field version
  • Fields don't work in Remoting (probably, I've never used remoting but I imagine they wouldn't)?

Other than these fairly rare cases, changing Foo to be a computed property later results in 0 lines of code changed.

Community
  • 1
  • 1
Robert Davis
  • 2,255
  • 2
  • 21
  • 21
  • 1
    Actually, changing a variable to a property is a breaking change. – Shane Fulmer Mar 03 '10 at 19:48
  • 1
    Sure it will break existing dlls, but it doesn't break the code. – Robert Davis Mar 03 '10 at 19:51
  • 5
    Mega dupe: http://stackoverflow.com/questions/1277572/should-i-use-public-properties-and-private-fields-or-public-fields-for-data, http://stackoverflow.com/questions/1216958/difference-between-automatic-properties-and-public-field-in-c-3-0, and related to http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c and http://stackoverflow.com/questions/205568/have-trivial-properties-ever-saved-your-bacon. Do we really need another one of these? – Aaronaught Mar 03 '10 at 19:53
  • @Aaronaught, I agree, I'd flag to close this. – CrimsonX Mar 03 '10 at 20:14
  • Using properties is preferable to using fields because you can change the statements in the get and set blocks without needing to change the classes that depend on the property. – SKARVA Bodavula Aug 23 '16 at 10:46

5 Answers5

70

Using properties has a couple of distinct advantages:

  • It allows for versioning if later you need extra logic. Adding logic to the getter or setter won't break existing code.
  • It allows data binding to work properly (most data binding frameworks don't work with fields).

In addition, there are almost no disadvantages. Simple, automatic properties like this get inlined by the JIT compiler, so there is no reason not to use them.

Also, you mentioned:

Other than these fairly rare cases, changing Foo to be a computed property later results in 0 lines of code changed.

This doesn't require your code to be changed, but it does force you to recompile all of your code. Changing from a field to a property is a breaking API change which will require any assembly which references your assembly to be recompiled. By making it an automatic property, you can just ship a new binary, and maintain API compatibility. This is the "versioning" advantage I mentioned above...

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    I tend to agree, the only reason you may not want to use a property is to handle `ref` or `out` requirements, although you can easily produce a temporary variable to use and then set the property to that variable which will be disposed soon after. – cossacksman Jul 20 '15 at 04:50
  • 1
    Using properties is preferable to using fields because you can change the statements in the get and set blocks without needing to change the classes that depend on the property. – SKARVA Bodavula Aug 23 '16 at 10:45
  • If you use the set block to check the value before assigning, you make it more difficult to reason about client code: `person.Name = ""; print(person)` might suggest that the Name was changed, but the setter might prevent it. In summary using the "set block" seems to me to be an anti feature. – Micha Wiedenmann Nov 16 '16 at 15:19
  • @MichaWiedenmann that is a matter of bad coding practices. If a bad value is rejected, it should be rejected with an exception. – Miguel Bartelsman Apr 26 '21 at 09:29
51

One good reason is that you can vary the get/set accessibility.

public int Foo {get; protected set;}
John Buchanan
  • 5,054
  • 2
  • 19
  • 17
  • 2
    Wow, I did not actually realise this. +1 and thanks – Tom 'Blue' Piddock Jan 31 '14 at 16:17
  • Though the `readonly` modifier for fields that only should ever be set in the constructor addresses many cases where this would be helpful. And, also, now that it is the future, you can do `public int Foo { get; }` (auto-implemented get-only property backed by a `readonly` field). – binki Sep 23 '16 at 15:49
  • I guess. for future changes you could make your variables properties instead of fields. but is there a good practice to define difference between variables or properties ? – Mike Jul 03 '18 at 19:28
31

A property is a language element which logically represents a property of the thing being modeled by the class. The class Car models a car; colour is a property of cars; therefore, Color is a property of Car.

A field is an language element which represents an implementation detail of the class. Your car does not have a "colour field", so your program's representation of a car should not expose a field called Color. It might contain a private implementation detail whereby the property Color is implemented by a field, but that's a private implementation detail, not a publically accessible part of the model.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    I like this explanation better, because it doesn't deny the fact that properties are in fact a redundant feature of the language, if you take this logical semantic out of the picture. The only remaining advocate in favor would be the reflection (like Reed mentions for data binding). But this can be achieved with annotations (attributes) on fields. – v.oddou Aug 24 '15 at 09:38
  • 8
    @v.oddou: Almost every feature of the language is redundant to something. Methods, for example, are unnecessary; methods could just be fields of delegate type initialized with lambdas. Redundancy is often thought of as a bad thing but it is not at all; redundancy makes things easier to understand. As I note in the answer, having two features, properties and fields, lets us subtly communicate to the reader whether the member is semantically important or just a mechanism of the type. – Eric Lippert Aug 24 '15 at 14:03
  • Why not start the two paragraphs with "A public field is a ...", and "A private field is a .."? What reason is then left to have properties? – Micha Wiedenmann Nov 16 '16 at 15:26
  • @MichaWiedenmann: Many properties cannot be replaced by a field. – Eric Lippert Nov 16 '16 at 18:00
  • @Eric: If field is an implementation detail, why can we make it public? – Karol Nov 17 '16 at 11:45
  • @Karol: Just because you can do a thing doesn't mean you should. Best practice in C# is to make fields private implementation details, and to use properties to represent business concepts. – Eric Lippert Nov 17 '16 at 15:23
  • @EricLippert: if you had the chance to redesign C# without any constraint of existing code breakage, would you allow public fields in a class? And protected fields? – Luca Cremonesi Nov 17 '16 at 16:17
  • @LucaCremonesi: In that counterfactual world there are lots of things I would fix, and this isn't one of them. There are language features which are genuinely *dangerously misleading*; where code that looks like it should work does not. There are language features which are *confusing* and *redundant*. Safety features in languages should be designed so that it is hard to write *wrong* programs; preventing people from violating minor best practice rules by making them illegal is often not the best use of time and effort. – Eric Lippert Nov 17 '16 at 17:54
  • @Eric: you very often say that features are not implemented by default and C# Team needs a justification to implement them. They did not start with C# that had all features and then took some of them out for some good reasons. Ability to specify access modifier for fields seems to be a feature. It looks like it was implemented by default and now it requires additional effort to remove it. If it is not true but we still agree that there is no real case to use it, why it was designed, specified, implemented, tested, documented and shipped? – Karol Nov 17 '16 at 19:50
  • 1
    @Karol: Well, there are pros and cons. For example: C# has to be able to interoperate well with other .NET languages, and it has to be familiar to users of Java and C++. And there are scenarios where for performance reasons you want to have direct access to a field of a struct, particularly for plain-old-data structures used for interoperability with C++. And you can't pass properties by ref. So it's not that there are zero use cases for them. But notice that all those use cases I named imply that fields are mechanisms. – Eric Lippert Nov 17 '16 at 20:33
8

Mostly because of convention.

The one solid argument for it is that if you later need to change from a field to a property, then all assemblies that reference yours will need to be recompiled.

Reflection does come into it once in a while, but very rarely. Some serialization types are based off of properties.

David Hogue
  • 1,791
  • 1
  • 14
  • 23
7

You can make properties virtual and override their implementation in derived classes. This is an important factor in many libraries that wrap your objects in generated proxy classes, e.g. the way NHibernate does to implement lazy loading. This isn't possible on fields.

JonoW
  • 14,029
  • 3
  • 33
  • 31
  • 1
    this is in complete denial that fields can be wrapped in accessors mutators and obtain the same feature. This is especially true because properties do just that usually, they wrap a field. (as long as they are not auto properties). And bam, back to square one, properties are useless. – v.oddou Aug 24 '15 at 09:41
  • @v.oddou And even technically auto properties wrap fields—just compiler-generated ones. It’s just syntax sugar! – binki Sep 23 '16 at 15:51