首页 > 解决方案 > FieldInfo.GetValue() 为嵌套的静态类公共静态字段返回 null

问题描述

我试图通过这个简单的代码在嵌套的静态类中获取归档值:

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",
        };

    }

}

一切似乎都很好,我认为这应该可行。但是调用field.GetValue(null)总是返回null。你知道我在这里错过了什么吗?提前致谢。

标签: c#.net-corereflectionc#-8.0.net-core-3.1

解决方案


欢迎来到静态初始化的美妙世界。静态成员按照声明的顺序进行初始化,并在orAll之前声明。因此,直到分配之后才分配。Role1Role2Role1Role2All

请注意,您对Lazy<T>此处的使用毫无意义:您立即调用.Value,这意味着LoadAllRolesAll. 如果All实际上是 a Lazy<T>(或者是包装 a 的属性Lazy<T>),并且Lazy<T>.Value在之后被调用并被初始化,则您不会看到此问题。Role1Role2

您可以将 和 的声明移到Role1类型Role2的顶部, above All,这“修复”了问题。不过,最好All在静态构造函数中进行分配,因为这样不太容易发生意外损坏:

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",
        };
    }
}

推荐阅读