dimanche 23 octobre 2016

Reflection GetValue of static field returns null

I've done my best to create a minimal reproduction of the problem I'm experiencing, but can't. Here at least is the bare minimum of the situation and we'll see if anyone has ideas.

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 One and Two:

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

Finally, get their values:

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

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, GetValue works fine on the parent type, but on the subtypes always yields null! (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 fieldInfos[1].GetValue(null) 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 MainType above.

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

System.Runtime.CompilerServices.RuntimeHelpers
  .RunClassConstructor(typeof(SubType).TypeHandle);

at the top before starting, but it didn't help (where SubType 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.





Aucun commentaire:

Enregistrer un commentaire