【问题标题】:Null Reference Exception for Class Lists类列表的空引用异常
【发布时间】:2016-07-21 17:43:43
【问题描述】:

我是编程新手,在创建具有另一个类的列表属性的类然后在 main 中访问它时遇到问题。在尝试将项目添加到列表后,我收到异常“对象引用未设置为对象的实例”,我在运行时收到此错误。我确实了解 List 引用为空,但我试图了解它为什么为空以及如何解决它。如果我只是在 main 中创建 List,我的代码将正常运行,但我希望将来将它作为一个类。就像我说的那样,我是 OOP 编程的新手,并试图获取一些关于为什么会发生这种情况的信息。如果这是一个重复的问题,我很抱歉。我的代码 sn-p 如下:

static void Main(string[] args)
    {
        BookList myBookList = new BookList();

        myBookList.bookList.Add(new Book("The Giver", "Lois Lowry", "Houghton Mifflin"));
        myBookList.bookList.Add(new Book("Telling Lies", "Paul Ekman", "Norton & Company"));
    }


class BookList
{
    public List<Book> bookList { get; set; }
}

class Book
{
    public Book(string title, string author, string publisher)
    {
        Title = title;
        Author = author;
        Publisher = publisher;
    }

    public string Title { get; set; }
    public string Author { get; set; }
    public string Publisher { get; set; }        
}

谢谢你,感谢所有的帮助!

【问题讨论】:

    标签: c# visual-studio-2015


    【解决方案1】:

    当您创建BookList 时,您实际上并没有初始化作为其成员的列表。您可以通过将初始化更改为:

    BookList myBookList = new BookList() {bookList = new List<Book>()};
    

    或者通过为BookList类编写一个初始化列表的构造函数;看起来像这样:

    class BookList
    {
        public List<Book> bookList { get; set; }
    
        public BookList(){ //New constructor
            bookList = new List<Book>();
        }
    }
    

    您收到此错误的原因是,当您创建了 BookList 的实例时,您实际上并没有确保 BookList 的内部 booklist 属性已初始化。就像您尝试这样做一样:

    List<string> newList;
    newList.Add("foo");
    

    这行不通,因为您只声明了newList,没有对其进行初始化。

    【讨论】:

    • 我强烈建议将 bookList = new List 放在单独的一行...
    • @Steve 一般来说,当有多个属性要初始化时,我倾向于只将它们放在换行符上,只是我的代码风格(我真的很喜欢单行)。如果您愿意,可以将列表初始化放在新行上。
    • 完美,谢谢先生,这解决了我的问题。也谢谢你的解释
    【解决方案2】:

    需要在default ctor中初始化Boolist.bookList

    class BookList
    {
        public BookList() { bookList = new List<Book>; } // <<<<
        public List<Book> bookList { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      您的问题在于您的public List&lt;Book&gt; bookList { get; set; } 课程中的BookList;你从来没有初始化它。例如,您可以在构造函数中执行此操作:

      class BookList
      {
          public List<Book> bookList { get; set; }
      
          public BookList
          {
              bookList = new List<Book>();
          }
      }
      

      请注意:属性应始终以 Pascal 大小写命名,即所有字母大写:BookList 而不是 bookList

      另外,因为用另一个List&lt;Book&gt; 实例替换你的BookList 并没有什么意义,我建议你将setter 上的访问修饰符设置为private 所以它只能被初始化一次,即在构造函数中:

      public List<Book> bookList { get; private set; } // notice the "private" set
      

      【讨论】:

      • 非常感谢,这解决了我的问题!另外,感谢您提供有关访问修饰符的提示,我才刚刚开始真正了解它们的目的。在类中执行此初始化而不是在主中执行此初始化正确吗?
      • 这取决于。答案可能会变得复杂(依赖注入、控制反转等);这在很大程度上取决于您的需求。
      • @Calskiez,一般来说,在类初始化中这样做是件好事,但在其他时候,您可能希望使用类提供的值以外的值来初始化此类属性。您可以为这种情况提供单独的 ctors,也可以在“新建”类时使用 { prop = value, ... } 语法初始化属性,如 Christ H 的回答中所述。
      猜你喜欢
      • 2011-05-16
      • 1970-01-01
      • 2015-11-01
      • 2013-09-21
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多