Recentely, I needed the same behavior of BindingFlags.FlattenHierarchy in WinRT that we are used to in .NET. At first, this didn’t work out because I was using the consumer preview, not the release preview.
In the release preview, Microsoft added great extensions methods as the RuntimeReflectionExtensions class. However, I was still facing issues where static base members were not returned by the extension methods. Below is an example of a unit test that will fail:
1: public class Foo
2: {
3: public static int StaticFooField;
4: }
5:
6: public class Bar : Foo
7: {
8: public static int StaticBarField;
9: }
10:
11: [TestClass]
12: public class ReflectionFacts
13: {
14: [TestMethod]
15: public void ReturnsAllStaticInheritedMembers()
16: {
17: var allItems = typeof(Bar).GetRuntimeFields().ToList();
18:
19: Assert.AreEqual(2, allItems.Count);
20: }
21: }
Where I would expect both fields to be returned, the GetRuntimeFields() method will only return all inherited non-static members. It does flatten the hierarchy for all non-static members though. However, I needed to achieve the same behavior as FlattenHierarchy | Static in my code.
I wrote lots of extension methods to achieve the same reflection code in both WinRT and .NET. Below shows how to walk down the stack to get the same behavior as FlattenHierarchy | Static:
1: /// <summary>
2: /// Gets the fields.
3: /// </summary>
4: /// <param name="typeInfo">The <see cref="TypeInfo"/>.</param>
5: /// <param name="bindingFlags">The binding flags.</param>
6: /// <returns>An array of <see cref="FieldInfo"/>.</returns>
7: /// <exception cref="ArgumentNullException">The <paramref name="typeInfo"/> is <c>null</c>.</exception>
8: public static FieldInfo[] GetFields(this TypeInfo typeInfo, BindingFlags bindingFlags)
9: {
10: Argument.IsNotNull("typeInfo", typeInfo);
11:
12: var flattenHierarchy = ShouldFlattenHierarchy(bindingFlags);
13: var source = flattenHierarchy ? typeInfo.AsType().GetRuntimeFields().ToList() : typeInfo.DeclaredFields.ToList();
14:
15: var includeStatics = Enum<BindingFlags>.Flags.IsFlagSet(bindingFlags, BindingFlags.Static);
16:
17: // TODO: This is a fix because static members are not included in FlattenHierarcy, remove when this is fixed in WinRT
18: if (flattenHierarchy)
19: {
20: var baseType = typeInfo.BaseType;
21: if ((baseType != null) && (baseType != typeof(object)))
22: {
23: source.AddRange(from member in GetFields(baseType.GetTypeInfo(), bindingFlags)
24: where member.IsStatic
25: select member);
26: }
27: }
28:
29: if (!includeStatics)
30: {
31: source = (from x in source
32: where !x.IsStatic
33: select x).ToList();
34: }
35:
36: return (from x in source
37: where x.IsStatic == includeStatics
38: select x).ToArray();
39: }
If you are interested in more reflection extensions, see this file.
WinRT is quite cool when you get it all working out 