How to Access Backing Fields Behind Auto-Implemented Properties

Is it possible to access backing fields behind auto-implemented properties?

I don't know about you, but I've written code in projects in other companies, and now I want to know how I did something! So it's usually quicker to do a web search for the answer, and it brought me here.

However, my reasons are different. I'm unit testing, and don't care what purists have to say, but as part of a setup for a unit test, I'm trying to invoke a certain state for a given object. But that state should be controlled internally. I don't want some other developer accidentally messing with the state, which could have far reaching effects upon the system. So it must be privately set! Yet how do you unit test something like that without invoking behaviours that (hopefully) will never happen? In such scenarios, I believe that using reflection with unit testing is useful.

The alternative is to expose things we don't want exposed, so we can unit test them! Yes, I've seen this in real life environments, and just thinking about it still makes me shake my head.

So, I'm hoping that the code below might be useful.

There are two methods here just for separation of concerns, really, and also to aid in readability. Reflection is head-spinning stuff for most developers, who in my experience either shy away from it, or avoid it like the plague!

private string _getBackingFieldName(string propertyName)
{
return string.Format("<{0}>k__BackingField", propertyName);
}

private FieldInfo _getBackingField(object obj, string propertyName)
{
return obj.GetType().GetField(_getBackingFieldName(propertyName), BindingFlags.Instance | BindingFlags.NonPublic);
}

I don't know what code conventions you work to, but personally, I like helper methods to be private and begin with a lower case letter. I don't find that obvious enough when reading, so I like the preceding underscore too.

There is discussion of backing fields, and their automatic naming. For the purpose of unit tests, you'll know pretty quickly if it has changed or not! It won't be catastrophic to your real code either, just the tests. So we can make simple assumptions about the naming of names—as I have above. You may disagree, and that's fine.

The more difficult helper _getBackingField returns one of those reflection types, FieldInfo. I've made an assumption here too, that the backing field you're after is from an object that's an instance, as opposed to being static. You can break that out into arguments to be passed in if you wish, but the waters will sure be muddier to the average developer who might want the functionality but not the understanding.

The handy thing about FieldInfos is that they can set fields on objects that match the FieldInfo. This is better explained with an example:

var field = _getBackingField(myObjectToChange, "State");
field.SetValue(myObjectToChange, ObjectState.Active);

In this case, the field is of an enumeration type called ObjectState. Names have been changed to protect the innocent! So, in the second line, you can see that by accessing the FieldInfo returned previously, I can call upon the SetValue method, which you might think should already relate to your object, but does not! This is the nature of reflection—FieldInfo separates a field from where it came from, so you must tell it what instance to work with (myObjectToChange) and thus, the value you want it to have, in this case, ObjectState.Active.

So to make a long story short, object-oriented programming will prevent us from doing such nasty things as accessing private fields, and worse, changing them when the developer of the code did not intend. Which is good! That's one of the reasons C# is so valuable, and liked by developers.

However, Microsoft gave us Reflection, and through it, we wield a mighty weapon. It may be ugly, and very slow, but at the same time, it exposes the innermost depths of the inner workings of MSIL (MicroSoft Intermediate Language)—IL for short—and enables us to pretty much break every rule in the book, this being a good example.

How do Auto-Implemented properties work in C# interfaces?

Why can I declare Auto-Implemented properties inside Interface

They aren't auto-implemented, it's just that the syntax of a property declaration is identical to the syntax for an auto-implemented property definition.

This:

interface IFoo
{
String Bar { get; set; }
}

Means: "IFoo has a public[1] String property named Bar which has a getter and a setter."

This:

class Foo
{
String Bar { get; set; }
}

Means: "Foo has a private[2] String property named Bar which has a getter and a setter, and the getter and setter are both auto-generated by the compiler and operate on a hidden instance field.


Note that the syntax used in the interface is unrelated to the syntax used by implementation in the class or struct. So given the same IFoo as above...

interface IFoo
{
String Bar { get; set; }
}

...we can have:

// Using auto-implemented property:
class Foo2 : IFoo
{
public String Bar { get; set; }
}
// Using explicit backing field:
class Foo3 : IFoo
{
private String bar;

public String Bar
{
get { return this.bar; }
set { this.bar = value; }
}
}
// Using expression-body syntax with a backing field:
class Foo4 : IFoo
{
private String bar;

public String Bar
{
get => this.bar;
set => this.bar = value;
}
}
// Using explicit interface implementation with a backing field:
class Foo5 : IFoo
{
private String bar;

String IFoo.Bar
{
get { return this.bar; }
set { this.bar = value; }
}
}


// You can also use explicit interface implementation with an auto-implemented property:
class Foo6 : IFoo
{
String IFoo.Bar { get; set; }
}
// However, if it's a getter-only property you won't be able to set a property value in the constructor - but you can initialize it inline:
interface IReadOnlyFoo
{
String Bar { get; }
}

class Foo7 : IReadOnlyFoo
{
String IReadOnlyFoo.Bar { get; } = "foo"; // ok
}

class Foo8 : IReadOnlyFoo
{
public Foo8()
{
this.Bar = "foo"; // <-- Error. `Bar` is not a member of `this`.
// You also can't cast `(IReadOnlyFoo)this` because `IReadOnlyFoo` does not contain a setter.
}

String IReadOnlyFoo.Bar { get; }
}


Is the private field in interfaces not generated the same as in classes

Interfaces don't have fields, interfaces only have virtual methods (or rather: an interface can be thought-of as a single vtable). Note that internally: properties and events are also fundamentally virtual methods (also note that while internally they're virtual calls, implemented interface methods are not automatically virtual (in the C# sense) in that a subclass of an interface implementation cannot arbitrarily override any interface member[3].

Also not to be confused with "Default interface implementations" in C# 8.0 which a more akin to extension methods than treating interfaces as classes, because interfaces still cannot have fields.

You should also familarise yourself with C#'s expression-bodied member syntax (though it isn't used much for property-setters):

class Foo2
{
String bar; // this is a private instance field

String Bar // this is a private instance property
{
get => this.bar;
set => this.bar = value;
}
}

[1] Disregarding Explicit Interface Implementation, of course.

[2] Class members are private by default if they don't have an explicit access-modifier.

[3] Subclasses can reimplement an interface which will have the effect of overriding any virtual-calls to that interface member, but only if the member is accessed through an interface reference rather than through an object reference to the class's supertype.

Auto-Implemented Property - signature of hidden member

Why not carry out a simple experiment?

using System.Reflection;

...

public class Experiment {
public int Age { get; set; }
}

...

var fieldNames = string.Join(", ", typeof(Experiment)
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.Select(field => field.Name));

Console.Write(fieldNames);

Outcome:

<Age>k__BackingField

Please, notice that unlike i_age actual field's name <Age>k__BackingField doesn't conflict with any field (we can't declare a field with such a name)

C# Auto-Implemented Properties Assistance

  1. this is called "Automatic Properties". (when you just write the set and the get method without any code inside them)
  2. the target of the Automatic Properties is the simplifying the coding process, and make it faster.
  3. when you write a property like the previous one.

    public Dictionary clientDict { get; set; }

the compiler translates it to the following

private Dictionary<string, string> _clientDic;

public Dictionary<string, string> clientDic
{
get { return _clientDic; }
set { _clientDic = value; }
}

and when you write a property like the following one

public int X {get;}

the compiler translates it to the following

private int _x;

public int X{
get { return _x; }
}

Does auto implemented properties have an implied set?

This is a newly introduced feature in C# 6.0. See the C# 6.0 Language specification, section 10.7.3 Automatically implemented properties:

If the auto-property has no set accessor, the backing field is
considered readonly (§10.5.2). Just like a readonly field, a
getter-only auto-property can also be assigned to in the body of a
constructor
of the enclosing class. Such an assignment assigns
directly to the readonly backing field of the property.

(Emphasis mine)



Related Topics



Leave a reply



Submit