17

Possible Duplicate:
What is the difference between a field and a property in C#

I'm a beginning programmer and I've read all about class properties. Books state that properties allow you to indirectly access member variables. Ok, so what makes it any different than just making the field public and accessing it directly?

Here's a quote from Learning C# 3.0 by Jesse Liberty:

For example, you might want external classes to be able to read a value, but not change it; or you might want to write some code so that the internal field can accept only values in a certain range. If you grant external classes free access to your member fields, you can’t control any of that.

I don't understand what he is saying here. Can someone further explain this or give an example of why I would want to use a property over making the field public. As I understand it now they would both accomplish the same exact thing...so I'm obviously missing something here.

Community
  • 1
  • 1
user1230593
  • 243
  • 1
  • 3
  • 9
  • Take a look at this site http://msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.80%29.aspx – MethodMan Aug 08 '12 at 22:59
  • The correct link is http://msdn.microsoft.com/en-us/library/79b3xss3.aspx. Please don't post version-specific links unless you only intend the link to be relevant for specific versions. – John Saunders Aug 08 '12 at 23:55

6 Answers6

11

The other answers provided so far provide details of the advantages of accessor/mutator logic, but all seem to miss out on the ideological point about object encapsulation.

You see, class member fields are an implementation detail. If you have a class that represents a collection, for example, then you could implement it as a linked list (and expose the root-node via a public field) or you could implement it as a resizable array and expose the index0 member.

The problem with revealing implementation details is that you lose any kind of defined interface between your class and its consumers. By ensuring all operations are done via defined methods (controlled by the class itself) you make it easier to work with and provide for a long-term viewpoint. For example, you are far more easily able to convert your collection implementation from one type (the linked-list) to another (the array) without breaking any contracts with your class' consumers.

Don't worry about any performance impact of trivial accessor/mutator methods: the JIT compiler will inline the property methods. If you'll run some benchmarks you'll see the performance of properties vs fields is identical.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • 2
    The best answer here. It's also worth mentioning that should it become necessary to change from an exposed field to a property at a later time, this also represents a contract change, and will require recompilation of all dependent code... particularly bad if you distribute a library. – spender Aug 08 '12 at 23:36
10

He's saying that properties can provide a getter but not a setter, therefore making them read-only (for example)

Properties are just syntactic sugar for a method e.g.

public int SomeProperty { get; set; }

is just sugar for

private int _someProperty;

public int SomeProperty_get() 
{
   return _someProperty;
}

public void SomeProperty_set(int value) 
{
   _someProperty = value;
}

This means that property setters/getters can apply logic that a mere public field can't

Edit: I'm not exactly sure what field names the CLR gives the backing fields for auto-properties - it's just an example :)

Edit2:

An example of a read only property:

public int SomeProperty { get; }

and finally a public read - private write (for autoproperties)

public int SomeProperty { get; private set; }

Really useful when you can't be bothered to type a backing field in :)

Just remember, if there is a possibility that you wish to apply logic to a member, then a property is the way to go. This is the way a lot of frameworks work (e.g. tracking 'dirty' objects by using a property to tell some sort of object manager that something has changed, this would not be possible using a public field)

Charleh
  • 13,749
  • 3
  • 37
  • 57
9

Properties can have side-effects, They provide syntactic sugar around 'getter' and 'setter' methods.

public class MyClass {

   int sizeValue = 0;

   public int Size {
      get {
         return sizeValue;
      }
      set {
         if ( value < 10 ) throw new Exception("Size too small");
         sizeValue = value;
      }
   }
}

Properties can also have different levels of protection for get and set, you cannot do that with fields.

public class MyOtherClass {

   // only this object can set this.
   public int Level {
      get; private set; 
   }

   // only things in the same assembly can set this.
   public string Name {
      get; internal set;
   }
}
IanNorton
  • 7,145
  • 2
  • 25
  • 28
  • I disagree with the pejorative "syntactic sugar". I honestly believe "properties" are much more than that. IMHO... – paulsm4 Aug 08 '12 at 23:10
  • 6
    I disagree with your interpretation of ["syntactic sugar"](http://en.wikipedia.org/wiki/Syntactic_sugar) as pejorative. It's called sugar because it's desirable. :) – Dan J Aug 08 '12 at 23:11
  • @paulsm4, It wasnt meant as a negative assertion, In addition to nicely wrapping get/set method logic you also get a different type for reflection which can be helpful. – IanNorton Aug 08 '12 at 23:11
  • You missed the main points (encapsulation, stable interface). – H H Aug 08 '12 at 23:41
3

There are a number of important differences between "properties" and "member access".

The most significant is that you can, through a property, make a member read-only (you can access the state, but you cannot change it). Just like "getter()" and "setter()" methods in Java.

You can also return a computed value from a property (generate a value "on-the-fly", as though it were a variable).

Dan J
  • 16,319
  • 7
  • 50
  • 82
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • doesn't warrant a new answer so I'll add it here: another biggie is being able to add data validation to your setter accessors. – Sam Axe Aug 08 '12 at 22:59
  • I think you may be confusing terms: you can make a *property* read-only. You cannot make a *member* read-only. – Dan J Aug 08 '12 at 23:00
  • @Dan J - I was trying to say 1) if your class had a member, and 2) if you wanted to provide read-only access to that member's value, then 3) "properties" are an excellent way to do it. I further mentioned that in Java, for lack of properties, providing a "getter()" method (with no corresponding "setter()") is the only way to accomplish the same thing. – paulsm4 Aug 08 '12 at 23:04
  • 1
    @DanJ: Sure I can; `public readonly string Foo;` – Ed S. Aug 08 '12 at 23:04
  • @Ed S: you're correct ;) – paulsm4 Aug 08 '12 at 23:05
  • One other note: "properties", I believe, were in large part inspired by Anders Hejlsberg's earlier work with Delphi (he's the architect of Borland Pascal, Delphi and C#, among many other achievements). – paulsm4 Aug 08 '12 at 23:07
  • @EdS. Right. I'm thinking from the perspective of code outside of the class; a read-only property that exposes a private field gives the declaring class write access while other classes have only read access. A `readonly` field can only be set during construction / initialization. @paulsm4 I misunderstood you, then. I thought you were saying that a difference between a property and a member is that a member can be made read-only. – Dan J Aug 08 '12 at 23:09
1

Properties can be configured so that:

they are read-only, Public MyProp {get;}

they are write-only Public MyProp {set;}

they are readable by external objects, but can only be set by the class's internals

Public MyProp {get; private set;}

As others have posted, you can also put logic into your getters and setters. For example before allowing the property to bet set to a new value, you can check that the value is acceptable.

You cannot do any of that with a public field.

Basically, a public field is the dumbest sort of property that you can have. Given that .Net now allows autobacking fields for your properties. There is no good reason to use public fields any longer.

DeanOC
  • 7,142
  • 6
  • 42
  • 56
  • Auto-implemented properties are nice, but the current compiler does not generate warnings about field misuse when you're using them (such as "field is never used" or "field is never assigned to and will always have a default value of null"). It makes catching these bugs slightly harder as they go by unnoticed. However I agree with you in spirit. – Dai Aug 08 '12 at 23:10
0

If you have Public Int MyAge I can set it to -200 or 20,000 and there is nothing you can do about it.

If you use a property you can check that age is between 0 and 150, for example.

Edit: as per IanNorton's example (man, that was fast)

Chuck Conway
  • 16,287
  • 11
  • 58
  • 101
Neil Thompson
  • 6,356
  • 2
  • 30
  • 53