Auto-Implemented Getters and Setters VS. Public Fields

Auto-implemented getters and setters vs. public fields

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.

Public Fields versus Automatic Properties

In a related question I had some time ago, there was a link to a posting on Jeff's blog, explaining some differences.

Properties vs. Public Variables

  • 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. For example:

    TryGetTitle(out book.Title); // requires a variable

C# autoproperty vs normal fields

AFAIK they behave exactly the same.

No they don't.

  • Fields can't be used in data binding (at least in some binding implementations)
  • You can add more logic later for properties without breaking source or binary compatibility
  • Properties can't be passed by reference
  • You can't add an initializer to an automatically implemented property
  • They'll clearly be different in terms of reflection
  • Philosophically, properties are logically part of the API whereas fields are an implementation detail

in c# you can always rewrite Foo into this: [...]

Well you can if you don't care about binary or source compatibility, yes. In some cases that's really not an issue - in other cases it's very, very much an issue. Why not make the choice to expose your API rather than your implementation details from the start? It's not like adding { get; set; } in your code is adding much clutter...

For more ranting, see my article on this.

Does auto-implemented properties take away the use for fields?

no, auto-implemented props do NOT remove the need for backing fields. Sometimes, a property getter/setter does more work then just hold a value. There are many cases where you may want a field. a very good example is when implementing INotifyPropertyChanged for binding.

like so:

class someClass : INotifyPropertyChanged
{
// details omitted.....

private int _myInt
public int myInt { get { return _myInt; }
set { if ( value == _myInt ) return;
_myInt = value;
RaiseNotify("myIng");
}}
}

this would be impossible without backing fields.

Advantage of set and get methods vs public variable

What I have seen someday on SO, as answer (written by @ChssPly76) why to use getters and setters

Because 2 weeks (months, years) from now when you realize that your
setter needs to do more than just set the value, you'll also realize
that the property has been used directly in 238 other classes :-)

there are much more advantages:

  1. getters and setter can have validation in them, fields can't
  2. using getter you can get subclass of wanted class.
  3. getters and setters are polymorphic, fields aren't
  4. debugging can be much simpler, because breakpoint can be placed inside one method not near many references of that given field.
  5. they can hide implementation changes:

before:

private boolean alive = true;

public boolean isAlive() { return alive; }
public void setAlive(boolean alive) { this.alive = alive; }

after:

private int hp; // change!

public boolean isAlive() { return hp > 0; } // old signature
//method looks the same, no change in client code
public void setAlive(boolean alive) { this.hp = alive ? 100 : 0; }

EDIT: one additional new advange when you are using Eclipse - you can create watchpoint on field, but if you have setter you need just a breakpoint, and... breakpoints (e.g. in setter method) can be conditional, watchpoints (on field) cannot. So if you want to stop your debugger only if x=10 you can do it only with breakpoint inside setter.

Why are C# auto-implemented properties public?

You are correct that auto-implemented properties that simply expose a backing field are not much of a gain over a public field.

As Alan Kay said:

But most people who use setters simply use them to simulate direct assignments to interior variables, and this violates the spirit and intent of real OOP.

However, there is an advantage to an auto-implemented property over a public field, and that is that it's a non-breaking change to later revise the implementation. If you have a public field, and code outside your class manipulates that public field, you can't change it to a private field in a future version of the class, or else any other code that touches that field will have to be recompiled. By contrast, once you have a public property, you can revise the implementation of that property in a future version, and client classes can continue using it with zero changes.

So it's useful to use auto-implemented properties for properties that right now would have trivial getter and setter implementations, but that may have more complex implementations in the future.

What is the purpose of auto-implemented properties if they are treated the same as public fields (C#)

public int Age {get; set;}

is equivilent to

private int _age;
public int Age { get { return _age; } set { _age = value; }

Isn't the first easier to write? Doesn't it follow the same best practices from Java?

And you can also use the private set or init set to lock them down easily. I think it saves lots of typing and makes it easy to modify the get/set command latter if needed.

Any reason to use auto-implemented properties over manual implemented properties?

It doesn't grant you anything extra beyond being concise. If you prefer the more verbose syntax, then by all means, use that.

One advantage to using auto props is that it can potentially save you from making a silly coding mistake such as accidentally assigning the wrong private variable to a property. Trust me, I've done it before!

Your point about auto props not being very flexible is a good one. The only flexibility you have is by either using private get or private set to limit scope. If your getters or setters have any complexity to them then the auto props are no longer a viable option.

Why do automatic properties require both getters AND setters?

If you didn't have a setter - then how would you ever set the property?

Incidentally, you can specify the accessibility, eg:

public string Foo
{
get;
private set;
}

Why do we need backing fields in C# properties?

Well, returning property itself leads to Stack Overflow exception:

public object Property 
{
get
{
return Property;
}
set
{
Property = value;
}
}

Imagine

  MyObject o = new MyObject();

// cause Stack Overflow exception
o.Property = null;

It easy to see why:

  1. setting Property = null calls set
  2. which call Property = value; which in turn calls set
  3. which call Property = value;... and so on.

So if property stores some value the value should be stored in a field (you need a field), we can't use a property to store itself. If you want to shorten the code, put it like this (auto properties):

  public object Property { 
get; // let .Net create a backing field for you
set;
}


Related Topics



Leave a reply



Submit