Почему возникает NullReferenceException? [дубликат]

93
24 февраля 2022, 06:30
На этот вопрос уже даны ответы здесь:
Что такое NullReferenceException, и как мне исправить код? (2 ответа)
Закрыт 2 года назад.

Выполняю одно из заданий курса по С#, которое звучит так:

Создать класс, представляющий учебный класс ClassRoom. Создайте класс ученик Pupil. В теле класса создайте методы void Study(), void Read(), void Write(), void Relax(). Создайте 3 производных класса ExcelentPupil, GoodPupil, BadPupil от класса базового класса Pupil и переопределите каждый из методов, в зависимости от успеваемости ученика. Конструктор класса ClassRoom принимает аргументы типа Pupil, класс должен состоять из 4 учеников. Предусмотрите возможность того, что пользователь может передать 2 или 3 аргумента. Выведите информацию о том, как все ученики экземпляра класса ClassRoom умеют учиться, читать, писать, отдыхать.

Основные пункты задания, которые определены в условии я, хоть и примитивно, но выполнил и решил добавить ещё метод GetInfo(), который бы выводил информацию о числе отличников, хорошистов и плохих учеников в классе. Для этого я обьявил массив в классе ClassRoom, который по идее должен принимать различное число элементов(инициализация проходив конструкторе).

В методе GetInfo() происходит перебор элементов массива и вычисление чисел различных видов учеников в классе.

Проблема состоит в том, что во время выполнения программы возникает исключение типа NullReferenceException, на строках инициализации массива. Выглядит так, будто поля pupil_1 - pupil_4 не определены, хотя выше в теле конструктора они определяются ссылками на обьекты.

Кроме того, возникает предупреждение "Field 'ClassRoom.pupils' is never assigned to, and will always have its default value null", чего тоже вроде как не должно быть, судя по тому, что я как раз таки и пытаюсь определить массив.

Делал различные проверки и никак не могу понять, в чём же проблема.

Буду очень рад и признателен любой подсказке.

using System;
namespace ConsoleApp1
{
class Program
{
    static void Main(string[] args)
    {
        ExcelentPupil a = new ExcelentPupil();
        GoodPupil b = new GoodPupil();
        BadPupil c = new BadPupil();
        ClassRoom class1 = new ClassRoom(a, b, c, c);
        ClassRoom class2 = new ClassRoom(a, b);
        Console.Read();
    }
}
abstract class Pupil
{
    public abstract string Study();
    public abstract string Read();
    public abstract string Write();
    public abstract string Relax();
}
class ExcelentPupil : Pupil
{
    public override string Read()
    {
        return "читает отлично";
    }
    public override string Study()
    {
        return "учится отлично";
    }
    public override string Write()
    {
        return "пишет отлично";
    }
    public override string Relax()
    {
        return "отдыхает отлично";
    }
}
class GoodPupil : Pupil
{
    public override string Read()
    {
        return "читает хорошо";
    }
    public override string Study()
    {
        return "учится хорошо";
    }
    public override string Write()
    {
        return "пишет хорошо";
    }
    public override string Relax()
    {
        return "отдыхает хорошо";
    }
}
class BadPupil : Pupil
{
    public override string Read()
    {
        return "читает плохо";
    }
    public override string Study()
    {
        return "учится плохо";
    }
    public override string Write()
    {
        return "пишет плохо";
    }
    public override string Relax()
    {
        return "отдыхает плохо";
    }
}
class ClassRoom
{
    Pupil pupil_1;
    Pupil pupil_2;
    Pupil pupil_3;
    Pupil pupil_4;
    Pupil[] pupils;
    public ClassRoom(Pupil pupil_1, Pupil pupil_2, Pupil pupil_3, Pupil pupil_4)
    {
        this.pupil_1 = pupil_1;
        this.pupil_2 = pupil_2;
        this.pupil_3 = pupil_3;
        this.pupil_4 = pupil_4;

        Console.WriteLine($"1 ученик {pupil_1.Read()}, {pupil_1.Study()}, {pupil_1.Write()}, {pupil_1.Relax()}");
        Console.WriteLine($"2 ученик {pupil_2.Read()}, {pupil_2.Study()}, {pupil_2.Write()}, {pupil_2.Relax()}");
        Console.WriteLine($"3 ученик {pupil_3.Read()}, {pupil_3.Study()}, {pupil_3.Write()}, {pupil_3.Relax()}");
        Console.WriteLine($"4 ученик {pupil_4.Read()}, {pupil_4.Study()}, {pupil_4.Write()}, {pupil_4.Relax()}");
        pupils[0] = this.pupil_1;
        pupils[1] = this.pupil_2;
        pupils[2] = this.pupil_3;
        pupils[3] = this.pupil_4;
        GetInfo();
    }
    public ClassRoom(Pupil pupil_1, Pupil pupil_2)
    {
        this.pupil_1 = pupil_1;
        this.pupil_2 = pupil_2;
        Console.WriteLine($"1 ученик {pupil_1.Read()}, {pupil_1.Study()}, {pupil_1.Write()}, {pupil_1.Relax()}");
        Console.WriteLine($"2 ученик {pupil_2.Read()}, {pupil_2.Study()}, {pupil_2.Write()}, {pupil_2.Relax()}");
        Console.WriteLine($"Про 3 и 4 учеников ничего не известно");
        pupils[0] = pupil_1;
        pupils[1] = pupil_2;
        GetInfo();
    }
    public void GetInfo()
    {
        byte numOfExlecent = 0, numOfGood = 0, numOfBad = 0;
        foreach (Pupil i in pupils)
        {
            if (i is ExcelentPupil) numOfExlecent++;
            else if (i is GoodPupil) numOfGood++;
            else if (i is BadPupil) numOfBad++;
        }
        Console.WriteLine($"В классе {numOfExlecent} отличных, {numOfGood} хороших и {numOfBad} плохих учеников");
    }
}
}
Answer 1
  1. Что такое NullReferenceException, и как мне исправить код?
  2. Причина в том, что массив pupils не инициализирован.
class ClassRoom
{
    Pupil pupil_1;
    Pupil pupil_2;
    Pupil pupil_3;
    Pupil pupil_4;
    Pupil[] pupils = new Pupil[4];
...
READ ALSO
групировка по нескольким столбцам c#

групировка по нескольким столбцам c#

Надо программно сделать аналог метода group by по нескольким полям на язык с #, но проблема в том, что эти поля заранее не определены, и в зависимости...

97
Ошибка	CS7036 помогите пофиксить [закрыт]

Ошибка CS7036 помогите пофиксить [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

148
Создание модели через рефлексию для сохранений Unity C#

Создание модели через рефлексию для сохранений Unity C#

Я новичок и пишу систему сохранений в Unity, которую хотелось бы использовать и в других своих проектахВ Интернете полно способов сделать сохранения...

69