Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do C# properties always have backup fields "behind the scene"?

Tags:

c#

properties

cil

I know that when we use properties in C#, the compiler always generate getters and setters for them in CIL (i.e., get_PropertyName and set_PropertyName), for example, consider the following piece of code:

    class Program
    {
        class Test
        {
            public string Name { get; set; }
        }
        static void Main(string[] args)
        {
            //Here I'm using reflection to inspect methods of Test class
            Type type = typeof(Test);
            foreach (var item in type.GetMethods())
            {
                Console.WriteLine(item.Name);
            }
        }
    } 

This program will produce output with the methods of Test, among which there will be get_Name and set_Name - the getter and setters I was talking about. From my understanding then, if getters and setter are created "behind the scenes" then there should be a backing field created as well from which/to which the getters and setter get/set values. So, from the previous example, I can use reflection to inspect fields for Test class, like that:

    static void Main(string[] args)
    {
        Type type = typeof(Test);
        foreach (var item in type.GetFields())
        {
            Console.WriteLine(item.Name);
        }
    } 

The ouput of this program is empty, I assume this is because the backing field that was created has private access, so we cannot see it. But since I don't know how to check it, can you please let me know if a backing field always gets created (even if we have a simple property with only get; and set;) ?

like image 908
Mykhailo Seniutovych Avatar asked Mar 30 '17 08:03

Mykhailo Seniutovych


1 Answers

If you mean simple properties like:

{get;set;}

or:

{get;}

then yes, there is a field; add BindingFlags.NonPublic | BindingFlags.Instance to your GetFields() call and you'll see it:

foreach (var item in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
    Console.WriteLine(item.Name);
}

It usually has an unpronouncable name involving <> - yours is <Name>k__BackingField on my machine - but: this name is a compiler feature (although a lot of serialization etc libraries make use of it, so it is unlikely to change).

But: no, properties don't by themselves always involve fields; for example:

public int Value => 42; // no field

or

public int Name { get { return obj.Name; } set { obj.Name = value; } }
like image 78
Marc Gravell Avatar answered Oct 20 '22 17:10

Marc Gravell