FieldInfo.GetValue () возвращает значение NULL для вложенных полей stati c class publi c stati c - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь получить полевые значения во вложенном классе stati c с помощью этого простого кода:

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. Ты хоть представляешь, что я здесь пропустил? Заранее спасибо.

1 Ответ

4 голосов
/ 05 марта 2020

Добро пожаловать в чудесный мир инициализации c. Члены Stati c инициализируются в том порядке, в котором они объявлены, а All объявляется до Role1 или Role2. Так что Role1 и Role2 не назначаются до тех пор, пока не будет назначено All.

Обратите внимание, что использование Lazy<T> здесь бессмысленно: вы немедленно звоните .Value, что означает, что LoadAllRoles вызывается во время инициализации All. Если All на самом деле было Lazy<T> (или было свойством, которое обернуло Lazy<T>), а Lazy<T>.Value было только , вызванным после инициализации Role1 и Role2, вы бы не t увидеть эту проблему.

Вы можете переместить объявления Role1 и Role2 в начало типа, выше All, что «решает» проблему. Вам бы лучше было присвоить All внутри конструктора stati c, так как он менее подвержен случайному повреждению:

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",
        };
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...