简体   繁体   中英

Do I have access to the variables in C# when using get and set?

When I do the following in a class:

public string ModifiedBy { get; set; }

How does C# store the data. Does the compiler generate a backing variable, how is it named and do I have access to it without using get; set?

Yes, the compiler generates a backing field.

No, you can't access it at compile time.

Yes, you can access it at runtime via reflection.

No, you shouldn't.


The easiest way to access the backing field of a property is, unsurprisingly, to implement a property with a backing field:

private int _myInt;
public int MyInt {
    get { return _myInt; }
    set { _myInt = value; }
}

If you want the ease of an auto-implemented property, but don't want everyone to be able to change its value, it might be appropriate to restrict the access modifier to one or other part of it, ie

public int MyInt { get; private set; } // or protected set etc

It stores it in a private backing field that gets generated by the compiler. The field is named something like <ModifiedBy>k__BackingField , and while it is possible to find it by reflection, but not necessarily a good idea to do so.

If you have a specific reason to access the field, you should change the property to use an explicit implementation with a defined backing field. But since by definition auto-properties do nothing but save and retrieve that value, I can think of no good reason to need to access that field if you're not already using more complex getters and setters.

That syntax is for an auto-implemented property . The backing variable is generated by the compiler, and you have no access to it.

That essentially compiles to something like:

private string __foo_1;   // Compiler-generated - cannot access.
public string ModifiedBy
{
    get { return __foo_1; }
    set { __foo_1 = value; }
}

You don't have access to it without reflection, but if you - this is how you can do it:

using System.Diagnostics;
using System.Linq;
using System.Reflection;

class Program
{
    internal class MyClass
    {
        public string MyProperty { get; set; }
    }

    static void Main(string[] args)
    {
        foreach (var mi in
                typeof(MyClass).GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)
                    .Where(m => m is FieldInfo))
        {
            Debug.WriteLine(mi.Name);
        }

        MyClass o = new MyClass();
        var fi = (FieldInfo)typeof(MyClass).GetMember(
            "<MyProperty>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic)[0];
        fi.SetValue(o, "Success");
        Debug.WriteLine(o.MyProperty);
    }
}

This gives the following output:

<MyProperty>k__BackingField
Success

In theory public auto property are just like a public variable. As already mentioned by many people; compiler will create the required private variable to hold the data. If you need to access the underlying private variable, go for hard coded variable name to avoid run-time exception.

However in reality we need to create auto property to make sure future development will not break the application that depent on this assembly.

Changing a public variable to a property is a breaking change . Ref the linked blog to understand it better.

You can't. The question is, though, why would you ever want to do that? If it's a speed issue, you're not required to use a property. Otherwise, there's really no reason I can see that you would need to access the backing variable for an auto-implemented property, as they have no side-effects and so function almost the same as normal fields.

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