ErikE ErikE - 1 year ago 228
C# Question

Reflection GetValue of static field returns null

Note: The following code actually works okay, but shows the scenario that is failing in my own solution. See the bottom of this post for more information.

With these classes:

public class MainType {
public static readonly MainType One = new MainType();
public static readonly MainType Two = SubType.Two;

public sealed class SubType : MainType {
public new static readonly SubType Two = new SubType();

Get fields

List<FieldInfo> fieldInfos = typeof(MainType)
.GetFields(BindingFlags.Static | BindingFlags.Public)
.Where(f => typeof(MainType).IsAssignableFrom(f.FieldType))

Finally, get their values:

List<MainType> publicMainTypes = fieldInfos
.Select(f => (MainType) f.GetValue(null))

In LinqPad or in a simple unit test class with the above code, everything works okay. But in my solution, where I have some unit tests that want to work with all instances of these fields,
works fine on the parent type, but on the subtypes always yields
! (If that happened here, the final list would be
{ One, null }
instead of
{ One, Two }
.) The test class is in a different project from the two types (each in their own file), but I've temporarily made everything public. I've dropped a breakpoint in and have examined all I can examine, and have done the equivalent of
in a Watch expression and it does in fact return null, despite the fact that there is a line in my main class exactly like the second one from

What is wrong? How do I get all the values of the subtype fields? How is it even possible for them to return null without an error?

On the theory that perhaps for some reason the subtype's class was not being statically constructed due to the access through reflection, I tried


at the top before starting, but it didn't help (where
is the actual subtype class in my project).

I'll keep plugging away at trying to reproduce this in a simple case, but I'm out of ideas for the moment.

Additional Information

After a bunch of fiddling, the code started working. Now it is not working again. I am working on reproducing what triggered the code to start working.

Note: Targeting .Net 4.6.1 using C# 6.0 in Visual Studio 2015.

Problem Reproduction Available

You can play with a working (failing) trimmed-down version of my scenario by downloading this somewhat minimal working example of the problem at github.

Debug the unit tests. When the exception occurs, step until you get to line 20 of GlossaryHelper.cs, and can see the return value of
in the
tab. You can see that indexes 3 through 12 are null.

Answer Source


The issue has nothing to do with Reflection but instead the circular dependency between the two static field initializers and the order of their execution.

Consider the following snippet:

var b = MainType.Two;
var a = SubType.Two;
Debug.Assert(a == b); // Success

Now let's exchange the first two lines:

var a = SubType.Two;
var b = MainType.Two;
Debug.Assert(a == b); // Fail! b == null

So what's going on here? Let's see:

  1. Code tries to access SubType.Two static field for the first time.
  2. The static initializer fires and executes the constructor of SubType.
  3. Since SubType inherits from MainType, the MainType constructor also executes and triggers MainType static initialization.
  4. The MainType.Two field static initializer is trying to access SubType.Two. Since static initializers are executed just once, and the one for SubType.Two is already executed (well, not really, it's currently executing, but is considered to be), it simply returns the current field value (null at that moment) which then is stored in MainType.Two and will be returned by further access requests for the field.

In short, the correct working of such design really depends of the order of the external access to the fields, so it's not surprising that it sometimes works, sometimes not. Unfortunately this is something you cannot control.

How to fix

If possible, avoid such static field dependencies. Use static readonly properties instead. They give you full control and also allows you to eliminate the field duplication (currently you have 2 different fields that hold one and the same value).

Here is the equivalent design without such issues (using C#6.0):

public class MainType
    public static MainType One { get; } = new MainType();
    public static MainType Two => SubType.Two;

public sealed class SubType : MainType
    public new static SubType Two { get; } = new SubType();

Of course this will require changing your reflection code to use GetProperties instead of GetFields, but I think it's worth it.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download