简体   繁体   中英

FieldInfo.GetValue() returns null for a nested static class public static fields

I'm trying to get filed values in a nested static class by this simple code:

public static class DataConstants {

    public static class Roles {

        public static readonly Role[] All = new Lazy<Role[]>(LoadAllRoles).Value;

        private static Role[] LoadAllRoles() {
            var fields = typeof(DataConstants.Roles)
                         .GetFields(BindingFlags.Public | BindingFlags.Static);

            foreach (var field in fields) {
                var r = field.GetValue(null);
            }
            return blah-blah;
        }

        public static readonly Role Role1 = new Role {
            Id        = -1,
            Name      = "role1",
        };

        public static Role Role2 = new Role {
            Id        = -2,
            Name      = "role2",
        };

    }

}

Everything seems to be fine and I think this should work. But calling the field.GetValue(null) always returns null . Have you any idea what I missed here? Thanks in advance.

Welcome to the wonderful world of static initialisation. Static members are initialised in the order that they're declared, and All is declared before Role1 or Role2 . So Role1 and Role2 aren't assigned until after All is assigned.

Note that your use of Lazy<T> here is pointless: you're immediately calling .Value , which means that LoadAllRoles is called during the initialisation of All . If All was actually a Lazy<T> (or was a property which wrapped a Lazy<T> ), and Lazy<T>.Value was only called after Role1 and Role2 were initialised, you wouldn't see this issue.

You can move the declarations of Role1 and Role2 to the top of the type, above All , which "fixes" the issue. You'd be better off assigning All inside a static constructor though, as this is less prone to accidental breakage:

public static class DataConstants {

    public static class Roles {
        public static readonly Role[] All;

        static Roles()
        {
            All = LoadAllRoles();   
        }

        private static Role[] LoadAllRoles() {
            var fields = typeof(DataConstants.Roles)
                         .GetFields(BindingFlags.Public | BindingFlags.Static);

            foreach (var field in fields) {
                var r = field.GetValue(null);
                Console.WriteLine("field: " + r);
            }

            return new Role[0];
        }

        public static readonly Role Role1 = new Role {
            Id        = -1,
            Name      = "role1",
        };

        public static Role Role2 = new Role {
            Id        = -2,
            Name      = "role2",
        };
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM