-1

Typically you want to encapsulate data by providing getters and setters for your internal state. Example:

public class Person {
    private int age;
    public int Age { 
        get { return age; }
        set { age = value; }
    }
}

void Main() {
    Person alice = new Person();
    alice.Age = 20;
}

But let's say we then have this happen:

public class Person {
    private int age;
    public int Age { 
        get { return age; }
        set { age = value; }
    }

    public String WhatIsMyAge() {
        return "My age is: " + ???;
    }
}

void Main() {
    Person alice = new Person();
    alice.Age = 20;

    Console.WriteLine(alice.WhatIsMyAge());
}

Is it better to use the property, or the field, here? Does it matter? Since we are inside the native class, do we still care about encapsulating the internals?

user3407764
  • 463
  • 1
  • 5
  • 15
  • `Age` is a poor choice for fields because it is mutable. `Birthdate` is a better choice. – Dour High Arch Feb 04 '18 at 20:28
  • 1
    Unless there is a very clear reason to use a field I always use properties. You will have a single point to look for if you need to change something (like if you want to calculate the age depending on a birthdate) – Steve Feb 04 '18 at 20:30
  • @DourHighArch I guess I get what you mean by it being a poor choice of it being mutable, but is that only because someone might accidentally change it, or is it a more programmatical concern? (thread-safety, for example) – user3407764 Feb 04 '18 at 20:35
  • 1
    you'd simply use the property. otherwise, why would you have one? – Fattie Feb 04 '18 at 20:35
  • 1
    There are many problems with mutable fields, including persistence, equality comparisons, race conditions; but the big problem with your example is correctness. If you detect `Age == 20` you have no way to know if it is correct; it might have changed since it was set. Yes, some times mutable fields are necessary but this is not such a case; Birthdate is immutable and you can calculate Age from that. – Dour High Arch Feb 04 '18 at 21:00

3 Answers3

2

If you are using simple properties without any extra functionality, it doesn't matter. However, in such case, why wouldn't you choose to use Auto-implemented properties ?

If your property getters or setters contain extra functionality, then it does matter offcourse whether or not you're using the property accessors or the backing fields directly. It all depends on the required behaviour then.

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
2

Always use the Property, especially in class code. I will go as far as saying: Accidentally using the backing field of a property in class code critical mistake.

A high amount of effort should be made to not accidentally using the backing field:

  • If you use autoimplement properties, there is no backing field name you could use accidentally. (well there is one of course, but it does not has a name; So using it accidentally is not possible).
  • If autoimplement Properties are not (no longer) enough, I always append a Underscore to the backing field. age and Age are much easier to mix up the _Age and Age.
  • Some people go beyond that. Like using a Dictionary<string, object> to be the backing field(s) for every class. Using "CallerMemberName" and simialr syntax sugar, figuring out the property name to use as Index can be trivial.
Christopher
  • 9,634
  • 2
  • 17
  • 31
  • 2
    Why is it a *critical* mistake ? – Frederik Gheysels Feb 04 '18 at 21:32
  • 1
    A large part of the point of having propertes (rather then raw fields) is the code you (may) call when you get and set them. But once you have other code (like the constructor) ignoring the properties and going for the backing field, you can never take that back without breaking code expecting that behavior. – Christopher Feb 04 '18 at 23:08
1

In your example:

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

You should use auto-implemented properties anyway.

But if you'd have a backing field to provide additional logic in a property's getters or setters, such as validation, definitely use the property instead of the backing field: this makes it impossible for the type to assign values to properties which wouldn't pass validation when assigned through the property's setter.

It should be safe to read the backing field, because getters shouldn't contain logic anyway. But for consistency, perform both read and write action through the property.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272