StackOverflowException при вызове свойства [дубликат]

238
06 февраля 2019, 18:10

На данный вопрос уже ответили:

  • StackOverflowException при использовании get/set 1 ответ

На последнем вызове print() выдает stackoverflow exception.А именно при вызове свойства programmingAVG.Там стоит проверка на null и что-то оно тупит

    class Student
    {
        string name;
        string surname;
        string patronymic;
        int bookNum;
        readonly string fullName;
        readonly int programmingAvg, AdminAvg, DesignAvg, allAvg;

        DateTime dt;
        int[][] marks = null;
        const int max = 12, min = 1;
        public enum Subject { Programming, Admin, Design };
        static string collageName = "Cambridge";
        static int studentCounter = 0;
        public Student(int[][] m, string name, string surname, string patronymic, int year, int month, int day)
        {
            int[] @null = new int[1] { 1 };
            bookNum = ++studentCounter;
            dt = new DateTime(year, month, day);
            this.name = name;
            this.surname = surname;
            this.patronymic = patronymic;
            marks = new int[3][];
            RemoveDigits();
            fullName = this.name + " " + this.surname + " " + this.patronymic;
            if(m!=null)
            setMarksProgramming(m[0]);
            else
            setMarksProgramming(@null);
            if (m!= null)
                setMarksAdmin(m[1]);
            else
                setMarksAdmin(@null);
           if (m!= null)
                setMarksDesign(m[2]);
            else
                setMarksDesign(@null);
            programmingAvg = marks[0].Sum() / marks[0].Length;
            AdminAvg = marks[1].Sum() / marks[1].Length;
            DesignAvg = marks[2].Sum() / marks[2].Length;
            allAvg = (programmingAvg + AdminAvg + DesignAvg) / 3;
        }
        public double? programmingAVG { get { if (marks!=null) return marks[0].Sum() / marks[0].Length; else return programmingAVG.GetValueOrDefault(-1); } }
        public double? adminAVG { get { if (marks != null) return marks[1].Sum() / marks[1].Length; else return programmingAVG.GetValueOrDefault(-1); } }
        public double? designAVG { get { if (marks != null) return marks[2].Sum() / marks[2].Length; else return programmingAVG.GetValueOrDefault(-1); } }
        public string Name
        {
            set { if (!string.IsNullOrEmpty(value)) this.name = value; else this.name = "null"; }
            get { return name; }
        }
        public string Surame
        {
            set { if (!string.IsNullOrEmpty(value)) this.surname = value; else this.surname = "null"; }
            get { return surname; }
        }
        public int Group { set; get; }
        public string Patronymic
        {
            set { if (!string.IsNullOrEmpty(value)) this.patronymic = value; else this.patronymic = "null"; }
            get { return patronymic; }
        }
        private void RemoveDigits()
        {
            name = Regex.Replace(name, "[0-9]", "", RegexOptions.IgnoreCase);
            surname = Regex.Replace(surname, "[0-9]", "", RegexOptions.IgnoreCase);
            patronymic = Regex.Replace(patronymic, "[0-9]", "", RegexOptions.IgnoreCase);
        }
        static public int countOfStudent() { return studentCounter; }
        public void setMarksProgramming(int[] param)
        {
            marks[0] = param;
        }
        public void setMarksAdmin(int[] param)
        {
            marks[1] = param;
        }
        public void setMarksDesign(int[] param)
        {
            marks[2] = param;
        }
        public void SetMark(Subject subject, int numLesson, int mark)
        {
            if (subject == Subject.Programming)
                if (numLesson >= 0 && marks[0].Length > numLesson)
                    if (mark <= max && mark >= min)
                        marks[0][numLesson] = mark;
                    else if (subject == Subject.Admin)
                        if (numLesson >= 0 && marks[1].Length > numLesson)
                            if (mark <= max && mark >= min)
                                marks[1][numLesson] = mark;
                            else if (subject == Subject.Design)
                                if (numLesson >= 0 && marks[2].Length > numLesson)
                                    if (mark <= max && mark >= min)
                                        marks[2][numLesson] = mark;
        }
        public void clear()
        {
            Array.Clear(marks, 0, marks.Length);
            marks = null;
        }
        public int AgeDate(DateTime DT)
        {
            return (DT - dt).Days / 365;
        }
        public int AgeNow
        {
            get { return (DateTime.Today - dt).Days / 365; }
        }
        public void print()
        {
            Console.Write($"\n{fullName}\n{AgeNow}\n{programmingAVG} {adminAVG} {designAVG}  {allAvg}\n{bookNum} {collageName}\n");
            Console.Write("Programming: ");
            if (marks[0] != null)
                for (int i = 0; i < marks[0].Length; i++)
                    Console.Write(marks[0][i] + " ");
            else
                Console.Write("NULL");
            Console.Write("\nAdmin: ");
            if (marks[1] != null)
                for (int i = 0; i < marks[1].Length; i++)
                    Console.Write(marks[1][i] + " ");
            else
                Console.Write("NULL");
            Console.Write("\nDesign: ");
            if (marks[2] != null)
                for (int i = 0; i < marks[2].Length; i++)
                    Console.Write(marks[2][i] + " ");
            else
                Console.Write("NULL");
            Console.Write("\n\n ");
        }
        static public int Max(Student[] m)
        {
            return m.Max(st => st.allAvg);
        }
        static public int Min(Student[] m)
        {
            return m.Min(st => st.allAvg);
        }
        static public int Count(Student[] m, int param)
        {
            if (param == 0)
            {
                return m.Count(st => st.programmingAvg >= 7);
            }
            else if (param == 1)
            {
                return m.Count(st => st.AdminAvg >= 7);
            }
            else if (param == 2)
            {
                return m.Count(st => st.DesignAvg >= 7);
            }
            else
                return -1;
        }
    }
    static void Main(string[] args)
    {
        int[][] m1 = null;//new int[3][] { new int[5] { 10, 11, 12, 7, 8 }, new int[4] { 7, 10, 11, 6 }, new int[4] { 10, 8, 2, 6 } };
        int[][] m2 = new int[3][] { new int[6] { 2, 4, 6, 2, 5, 8 }, new int[4] { 2, 3, 12, 6 }, new int[3] { 8, 7, 7 } };
        int[][] m3 = new int[3][] { new int[4] { 5, 4, 6, 6, }, new int[5] { 7, 5, 5, 4, 6 }, new int[4] { 12, 8, 12, 9 } };
        Console.WriteLine(Student.countOfStudent());
        Student[] arr = new Student[] { new Student(m1, "Iv35a6n", "Chyp2ko", "Oleksobych", 1978, 5, 3), new Student(m2, "Olya", "Chaban", "Olegivna", 1996, 10, 13), new Student(m3, "Misha", "Onyuk", "Petrovich", 2001, 1, 31) };
        arr[0].print();
        arr[1].print();
        arr[2].print();
        Console.Write("\n\n");
        Console.Write("MAX = " + Student.Max(arr));
        Console.Write("  MIN = " + Student.Min(arr));
        Console.Write("\n\n");
        Console.Write("ProgrammingGood = " + Student.Count(arr, 0) + "  AdminGood = " + Student.Count(arr, 1) + "  DesignGood = " + Student.Count(arr, 2));
        Console.Write("\n\n");
        arr[0].Group = 1;
        Console.Write(arr[0].Group + "\n");
        DateTime d = new DateTime(2002, 6, 12);
        Console.WriteLine(Student.countOfStudent());
        Console.Write("\n2002 6 12 = " + arr[0].AgeDate(d));
        for (int i = 0; i < 5; i++)
            arr[0].SetMark(0, i, 12);
        arr[0].print();
        arr[0].clear();
        arr[0].print();
     }
Answer 1

У Вас ошибка, вызывающая бесконечную рекурсию.

public double? programmingAVG 
{ 
    get 
    { 
        if (marks!=null) 
            return marks[0].Sum() / marks[0].Length; 
        else 
            return programming**AVG**.GetValueOrDefault(-1); 
    } 
}

Вместо того, чтобы брать значение поля programmingAvg, вы опять берёте значение (т.е. вызываете метод Get) свойства programmingAVG. Как результат - бесконечная рекурсия и StackOverflowException.

Ну и сопутствующая мелочь - поле programmingAvg у Вас целое, а свойство - double. И оценки - целые. Так что деление по итогу даст целое число. Добавьте приведение к double одного из аргументов (равно как и в конструкторе, когда вычисляете значение programmingAvg).

Answer 2

nullreference exception потому что в методе clear - Вы установили null, а в принте без проверки на null - пытаетесь сразу же обратится к проверке на налл по индексу - if (marks[0] != null) , хотя весь массив налл, а не отдельный элемент массива

READ ALSO
Ошибка C# , класс не содержит определения

Ошибка C# , класс не содержит определения

С горем пополам написал функцию для передачи значений из выпадающего списка в матрицу (matrix_dimensions_changed), но на выходе ошибка с кодом CS1061 - «MainWindow»...

241
Selenium смена FirefoxOptions в процессе выполнения тестов

Selenium смена FirefoxOptions в процессе выполнения тестов

При запуске браузера, настройки успешно устанавливаются

257
Вопрос по ориентации экрана и UI

Вопрос по ориентации экрана и UI

Как сделать, так, чтобы при переключении на альбомную ориаентацию в игре, отключалась одна Panel, и запустилась другая? Можно ли со скрипта как...

225