stati c инициализация класса со ссылками на stati c - PullRequest
0 голосов
/ 07 августа 2020

Почему в следующем коде Library.genres[n].booklist имеют значение NULL во время выполнения для всех элементов в Library.genres? Так же, как если бы определения для dramabooks и kidsbooks не учитывались для инициализации stati c:

static class Library
{
   public static List<Genre> genres = new List<Genre>()
   {
      new Genre("Drama", dramabooks),
      new Genre("Kids", kidsbooks)
   };

   public static List<Book> dramabooks = new List<Book>() {
      new Book("book1"), 
      new Book("book2")
   };

   public static List<Book> kidsbooks = new List<Book>(){
      new Book("book3"),
      new Book("book4")
   };
}

class Genre
{
   string catname;
   List<Book> booklist;

   Genre(string catname, List<Book> booklist)
   {
      this.catname = catname;
      this.booklist = booklist;
   }
}

class Book
{
   string title;

   Book(string title)
   {
      this.title = title;
   }
}

1 Ответ

1 голос
/ 07 августа 2020

Не обращая внимания на любые другие ошибки кода (а их много). Это связано с тем, как stati c поля инициализируются в том текстовом порядке, в котором они появляются. kidsbooks и dramabooks не были инициализированы при инициализации genres

Из ECMA C# Спецификации

15.5. 6.2 Инициализация поля Stati c

Инициализаторы переменных поля stati c класса соответствуют последовательности присваиваний, которые выполняются в текстовом порядке, в котором они появляются в классе декларация (§15.5.6.1). Внутри частичного класса значение «текстового порядка» определяется §15.5.6.1. Если в классе существует конструктор stati c (§15.12), выполнение инициализаторов поля stati c происходит непосредственно перед выполнением этого конструктора stati c. В противном случае инициализаторы поля stati c выполняются во время, зависящее от реализации, до первого использования поля stati c этого класса.

Короче говоря, используйте stati c конструктор, в котором вы можете express порядок инициализации явно, он менее подвержен ошибкам и более декларативен

static class Library
{
   static Library()
   {

      dramabooks = new List<Book>()
      {
         new Book("book1"),
         new Book("book1")
      };

      kidsbooks = new List<Book>()
      {
         new Book("book3"),
         new Book("book4")
      };
      genres = new List<Genre>()
      {
         new Genre("Drama", dramabooks),
         new Genre("Kids", kidsbooks)
      };

   }

   public static List<Genre> genres;

   public static List<Book> dramabooks;

   public static List<Book> kidsbooks;
}
...