Auto-implemented getters and setters vs. public fields

I see a lot of example code for C# classes that does this:

public class Point {
public int x { get; set; }
public int y { get; set; }
}

Or, in older code, the same with an explicit private backing value and without the new auto-implemented properties:

public class Point {
private int _x;
private int _y;


public int x {
get { return _x; }
set { _x = value; }
}


public int y {
get { return _y; }
set { _y = value; }
}
}

My question is why. Is there any functional difference between doing the above and just making these members public fields, like below?

public class Point {
public int x;
public int y;
}

To be clear, I understand the value of getters and setters when you need to do some translation of the underlying data. But in cases where you're just passing the values through, it seems needlessly verbose.

38680 次浏览

It encapsulates setting and accessing of those members. If some time from now a developer for the code needs to change logic when a member is accessed or set it can be done without changing the contract of the class.

You never know if you might not need some translation of the data later. You are prepared for that if you hide away your members. Users of your class wont notice if you add the translation since the interface remains the same.

The biggest difrence is that, if ever you change your internal structure, you can still maintain the getters and setters as is, changing their internal logic without hurting the users of your API.

It's also much simpler to change it to this later:

public int x { get; private set; }

I tend to agree (that it seems needlessly verbose), although this has been an issue our team hasn't yet resolved and so our coding standards still insist on verbose properties for all classes.

Jeff Atwood dealt with this a few years ago. The most important point he retrospectively noted is that changing from a field to a property is a breaking change in your code; anything that consumes it must be recompiled to work with the new class interface, so if anything outside of your control is consuming your class you might have problems.

If you have to change how you get x and y in this case, you could just add the properties later. This is what I find most confusing. If you use public member variables, you can easily change that to a property later on, and use private variables called _x and _y if you need to store the value internally.

The idea is that even if the underlying data structure needs to change, the public interface to the class won't have to be changed.

C# can treat properties and variables differently at times. For example, you can't pass properties as ref or out parameters. So if you need to change the data structure for some reason and you were using public variables and now you need to use properties, your interface will have to change and now code that accesses property x may not longer compile like it did when it was variable x:

Point pt = new Point();
if(Int32.TryParse(userInput, out pt.x))
{
Console.WriteLine("x = {0}", pt.x);
Console.WriteLine("x must be a public variable! Otherwise, this won't compile.");
}

Using properties from the start avoids this, and you can feel free to tweak the underlying implementation as much as you need to without breaking client code.

AFAIK the generated CIL interface is different. If you change a public member to a property you are changing it's public interface and need to rebuild every file that uses that class. This is not necessary if you only change the implementation of the getters and setters.

Also to be considered is the effect of the change to public members when it comes to binding and serialization. Both of these often rely on public properties to retrieve and set values.

Maybe just making fields public you could leads you to a more Anemic Domain Model.

Kind Regards

Setters and getters are bad in principle (they are a bad OO smell--I'll stop short of saying they are an anti-pattern because they really are necessary sometimes).

No, there is technically no difference and when I really want to share access to an object these days, I occasionally make it public final instead of adding a getter.

The way setters and getters were "Sold" is that you might need to know that someone is getting a value or changing one--which only makes sense with primitives.

Property bag objects like DAOs, DTOs and display objects are excluded from this rule because these aren't objects in a real "OO Design" meaning of the word Object. (You don't think of "Passing Messages" to a DTO or bean--those are simply a pile of attribute/value pairs by design).

Setter and Getter enables you to add additional abstraction layer and in pure OOP you should always access the objects via the interface they are providing to the outside world ...

Consider this code, which will save you in asp.net and which it would not be possible without the level of abstraction provided by the setters and getters:

class SomeControl
{


private string _SomeProperty  ;
public string SomeProperty
{
if ( _SomeProperty == null )
return (string)Session [ "SomeProperty" ] ;
else
return _SomeProperty ;
}
}

Since auto implemented getters takes the same name for the property and the actual private storage variables. How can you change it in the future? I think the point being said is that use the auto implemented instead of field so that you can change it in the future if in case you need to add logic to getter and setter.

For example:

public string x { get; set; }

and for example you already use the x a lot of times and you do not want to break your code.

How do you change the auto getter setter... for example for setter you only allow setting a valid telephone number format... how do you change the code so that only the class is to be change?

My idea is add a new private variable and add the same x getter and setter.

private string _x;


public string x {
get {return _x};
set {
if (Datetime.TryParse(value)) {
_x = value;
}
};
}

Is this what you mean by making it flexible?

Also, you can put breakpoints on getters and setters, but you can't on fields.

It is also worth noting that you can't make Auto Properties Readonly and you cannot initialise them inline. Both of these are things I would like to see in a future release of .NET, but I believe you can do neither in .NET 4.0.

The only times I use a backing field with properties these days is when my class implements INotifyPropertyChanged and I need to fire the OnPropertyChanged event when a property is changed.

Also in these situations I set the backing fields directly when values are passed in from a constructor (no need to try and fire the OnPropertyChangedEvent (which would be NULL at this time anyway), anywhere else I use the property itself.

why we dont just use public fields instead of using properties then call accessors ( get,set ) when we dont need to make validations ?

  1. A property is a member that provides a flexible mechanism to read only or write only
  2. Properties can be overridden but fields can't be.

Adding getter and setter makes the variable a property as in working in Wpf/C#.

If it's just a public member variable, it's not accessible from XAML because it's not a property (even though its public member variable).

If it has setter and getter, then its accessible from XAML because now its a property.