C# 使用静态引用进行静态类初始化

C# 使用静态引用进行静态类初始化,c#,static,C#,Static,在下面的代码中,为什么Library.genres[n].booklist在运行时对Library.genres中的所有项目都为空?就像在静态初始化中没有考虑剧本和儿童书的定义一样: static class Library { public static List<Genre> genres = new List<Genre>() { new Genre("Drama", dramabooks), new Genr

在下面的代码中,为什么
Library.genres[n].booklist
在运行时对
Library.genres
中的所有项目都为空?就像在静态初始化中没有考虑
剧本
儿童书
的定义一样:

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;
   }
}
静态类库
{
公共静态列表类型=新列表()
{
新体裁(“戏剧”,剧本),
新类型(“儿童”,儿童书)
};
公共静态列表书籍=新列表(){
新书(“第一册”),
新书(“第二册”)
};
公共静态列表kidsbooks=新列表(){
新书(“第三册”),
新书(“第四册”)
};
}
班级类型
{
字符串catname;
书单;
流派(字符串catname、列表booklist)
{
this.catname=catname;
this.booklist=booklist;
}
}
课堂用书
{
字符串标题;
书(字串标题)
{
this.title=标题;
}
}

忽略任何其他代码错误(而且有很多错误),这是由于静态字段的初始化方式,这是按照它们出现的文本顺序进行的<当
genres
初始化时,code>kidsbooks和
剧本
尚未初始化

15.5.6.2静态字段初始化

类的静态字段变量初始值设定项对应于 按中的文本顺序执行的赋值序列 它们出现在类别声明中(§15.5.6.1)。在一段时间内 “文本顺序”的含义由 §15.5.6.1. 如果类中存在静态构造函数(§15.12), 静态字段初始值设定项的执行发生在 执行静态构造函数。否则,静态场 初始值设定项在执行之前在依赖于实现的时间执行 该类静态字段的首次使用

简而言之,使用一个静态构造函数,您可以显式地表达初始化的顺序,它不太容易出错,而且更具声明性

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;
}
静态类库
{
静态库()
{
戏剧书籍=新列表()
{
新书(“第一册”),
新书(“第一册”)
};
kidsbooks=新列表()
{
新书(“第三册”),
新书(“第四册”)
};
类型=新列表()
{
新体裁(“戏剧”,剧本),
新类型(“儿童”,儿童书)
};
}
公共静态列表类型;
公共静态图书目录;
公共静态列表儿童书;
}

您是否尝试在所有初始化代码上设置断点以查看初始化顺序@jonskeet有一篇关于静态初始化所涉及的更精细(/更奇怪)规则的博文,这是因为体裁是实例。首先,你要声明的是静态成员,比如剧本和儿童书。若要初始化它们,则需要使用库类的构造函数。我的意思是从静态构造函数初始化。谢谢,回答得很好。我添加了新书构造器,这是我在写这篇文章时错过的,只是为了让文章完整,这样其他人在你回答后会发现它很有用。