Access auto property backing field with reflection
Access property fields of auto property in C#
Using reflection you can easily access any property, filed, methods, pretty much anything of any type in .NET. Reflection is never the most elegant way to do something, but sometime you just have to do it.
In older versions of C#, to declare a simple property in a class you would have to declare a private field which will be exposed by the property outside the class
public class Person { private string name; public string Name { get { return this.name; } set { this.name = value; } } private string mail; public string Mail { get { return this.mail; } set { this.mail = value; } } }
Accessing private fields mail and name is pretty easy with reflection on a class which is organized like this
var person = new Person(); var mailField = person.GetType().GetField("mail", BindingFlags.NonPublic | BindingFlags.Instance); mailField.SetValue(person, "mymail@mydomain.com");
Starting from C# 3.0 Microsoft introduced auto properties. This feature allows you to create properties without declaring private methods to store the data for the property of the class
public class Person { public string Name { get; set; } public string Mail { get; set; } }
As you can see, code is significantly reduced and you have the same functionality. Pretty cool stuff, but unfortunately our reflection code will not work on the class like this.
As you can see, we do not have private fields in the class named mail and name, so reflection will not be able to locate them. This update from Microsoft is basically only masking to make developers life easier, in the back-end it is still the same approach with private fields, but as the property is now auto-created, fields are created with generic names.
The pattern for private fields name is <Property name>k__BackingField
So, private fields for Mail and Name property in previous class are still here, but their names are now <Name>k_BackingField and <Mail>k_MackingField
In reflection snippet code from above we would just replace the name of the field we are trying to access
var person = new Person(); var mailField = person.GetType().GetField(string.Format("<{0}>k_BackingField","Mail"), BindingFlags.NonPublic | BindingFlags.Instance); mailField.SetValue(person, "mymail@mydomain.com");
References
Disclaimer
Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
Comments for this article