0

In the following code, why Library.genres[n].booklist are null at runtime for all items in Library.genres? Just like if the definitions for dramabooks and kidsbooks were not being considered for the static initialization:

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;
   }
}
2
  • Have you tried putting breakpoints on all your initialization code to see the order of initialization? @jonskeet has a good blog post on the finer (/weirder) rules involved in static initialization Commented Aug 7, 2020 at 4:21
  • this is because Genre is instance. first thing you have just declare static members dramabooks and kidsbooks. you want initialize them then you need to use constructor of Library class. I mean you initialize from static constructor. Commented Aug 7, 2020 at 4:24

1 Answer 1

1

Disregarding any other code errors (and there are many), This is due to how static fields initialise, which is in the textual order of which they appear. kidsbooks and dramabooks haven't been initialised when genres initialises

From the ECMA C# Specifications

15.5.6.2 Static field initialization

The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration (§15.5.6.1). Within a partial class, the meaning of "textual order" is specified by §15.5.6.1. If a static constructor (§15.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.

In short, use a static constructor where you can express the order of initialisation explicitly, it's less prone to error and more declarative

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, excellent answer. I added the new Book constructor which I missed when writing the post, just for completeness of the post, and so that other people find it useful after your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.