0

I am having a hard time understanding how properties are "connected" to backing fields. I've set up a common example. I often see get and set simplified to {get; set;}. Is this only appropriate when one field is present or can it still work with two same-type fields. If it does work, is the name property in this code acting on behalf of name or address or both? I'm having a hard time understanding the importance of the private field if the information that would be stored there is stored/accessed in a public property. Is that making sense?

using System;

namespace MyApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      Person myObj = new Person();
      myObj.Name = "Liam";
      Console.WriteLine(myObj.Name);
    }
  }
  class Person
  {
    private string name;
    private string address; 
    public string Name {get; set;}  
  }
  
}
rene
  • 41,474
  • 78
  • 114
  • 152
Bishibro
  • 23
  • 5
  • [Suggested starting point](https://stackoverflow.com/q/6001917/1070452) – Ňɏssa Pøngjǣrdenlarp Sep 14 '22 at 17:45
  • Properties per se are not necessarily "connected" with backing fields. For auto-implemented properties (those with only a `{get;}` or `{ get; set; }` declaration) the compiler generates a backing field, not you. The backing field is discoverable through reflection, if you are curious. For other properties with explicit implementation (i.e., not auto-implemented), whether they are backed by a backing field is dependend on the getter/setter code written... –  Sep 14 '22 at 17:45
  • What you have in your current example is an [auto property](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties). Basically when you simplify `get` and `set` like that, the compiler actually creates a backing field for it on it's own. `get` returns the value of the field, and `set` sets it. You adding your own private field and not connecting the property to it still makes the property an auto property, so your private field is not being used at all. – Jesse Sep 14 '22 at 17:46
  • In your case, the property `Name` is not related to the field `name` at all. 20 years ago, when .NET was first released, you'd implement a simple property like this: `public string Name { get { return name; } set { name = value; } }`. Then the language got _automatic properties_ with hidden backing fields. So `public string Name { get; set; }` was born, and no explicit backing fields were needed – Flydog57 Sep 14 '22 at 17:48
  • The purpose of properties is access control. A public property with a private backing field gives the internal class unrestricted access to read and change the private field while the public property can contain logic that has the final say in what code outside of the current class can `get` from the field or `set` the field to. – Jesse Sep 14 '22 at 17:49
  • Have you tried removing `name`? What happened? – ctrl-alt-delor Sep 14 '22 at 17:57
  • This was all very helpful! Thank you all! – Bishibro Sep 14 '22 at 18:20

2 Answers2

0

public string Name {get; set;} is an auto-implemented property which will have it's own backing field generated by the compiler with name something like <Name>k__BackingField. You can see it using decompiler, for example online one - sharplab.io which will show something like this as output:

internal class Person
{
    private string name;

    private string address;

    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string <Name>k__BackingField;

    public string Name
    {
        [CompilerGenerated]
        get
        {
            return <Name>k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            <Name>k__BackingField = value;
        }
    }
}

Note that generated property name starts with < symbol which can't be used by application developer as part of identifier name, so this way compiler avoids naming conflicts with developer defined ones.

So as you can see your Name property will have not connection to name and address fields declared in the same class.

If you need you can define your property with backing field manually (usually it is done when there is some extra logic around):

class Person
{
    private string _name;

    public string Name
    {
        get => _name;
        set => _name = value;
    }
}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
0

You don't need properties with backing fields. Particularly if they are publicly read-able and write-able.

No backing fields

There are a number of options without backing fields.

Public setters and getters

// inline value initialisation
var p1 = new Person()
{
    Name = "John"
};

// instantiation + setting
var p2 = new Person();
p2.Name = "John";

class Person
{
    public string Name {get; set;}  
}

Public getters, private setters

// inline value initialisation
var p1 = new Person("John");

class Person
{
    public string Name {get; private set;} 

    public Person(string name)
    {
        this.Name = name;
    }
}

Or ...

// inline value initialisation
var p1 = new Person();
p1.SetSomeProps("John");

class Person
{
    public string Name {get; private set;} 

    public void SetSomeProps(string name)
    {
        this.Name = name;
    }
}

With backing fields

// inline value initialisation
var p1 = new Person()
{
    Name = "John"
};

// instantiation + setting
var p2 = new Person();
p2.Name = "John";

class Person
{
    private string theName = string.Empty;

    public string Name
    {
        get
        {
            return this.theName;
        }

        set(string value)
        {
            this.theName = value;
        }

    }  
}
  • Technically, auto-implemented properties like your `public string Name {get; set;}` use backing fields. It's just not the programmer, but rather the compiler who will declare the backing field for auto-implemented properties (hence "auto"). The backing field for auto-implemented properties are there, both discoverable through reflection and by inspecting the IL code generated by the compiler. So, in a sense it's wrong to say that auto-implemented props are without backing field. Correctly: auto-implemented props don't need the programmer to declare a backing field for them explicitly –  Sep 14 '22 at 18:01
  • @MySkullCaveIsADarkPlace I am well aware of that, but the key to the example is that the developer doesn't write code with them in. – Benjamin James Kippax Sep 14 '22 at 18:10