简体   繁体   中英

I need someone to correct my thinking on C# Properties (get & set)

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;}  
  }
  
}

public string Name {get; set;} 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;
    }
}

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;
        }

    }  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM