Получите неожиданное исключение StackOverflow при использовании свойств и унаследованного конструктора - PullRequest
0 голосов
/ 14 октября 2019

Игра (по дидактическим причинам) с наследованием и свойством в C # a получила странное исключение. Должно быть, пирог для экспертов, но все же сбивает с толку меня. Вот мой код:

public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }
    }
public class Employee : Person
    {
        public int ID
        {
            get
            {
                return ID;
            }
            set
            {
                if (ID < 0 || ID > 999)
                    throw new Exception("Id must between [000-999]");
                ID = value;
            }
        }

        public Employee(string name, int age, int id):base(name, age)
        {
            ID = id;
        }
    }

static void Main(string[] args)
        {
            var per = new Person("John", 32);
            var imp = new Employee("Michael", 44, 330);
         }

Выполнение, что я получил StackOverflow. Последнее StackTrace указывает на что-то не так в строке Employee.get_ID () внутри класса Employee.

Заранее благодарим за любую помощь!

1 Ответ

3 голосов
/ 14 октября 2019

Ну, свойство ID возвращает само по себе

    public int ID
    {
        get
        {
            return ID;
        }
    ...

и, таким образом, у вас переполнение стека : когда вы читаете ID, оно вызывает IDкоторый в свою очередь вызывает ID и т. д. Та же проблема с set: вы присваиваете значение свойству ID, что приводит к присвоению значения ID и т. д. Чтобы разорвать этот замкнутый круг , давайте представим вспомогательное поле

    private int m_ID;

    public int ID
    {
        get
        {
            //DONE: now we just read m_ID, not call the property
            return m_ID;
        }
        set
        {
            //DONE: you want to validate value, not ID, right?
            //DONE: ArgumentOutOfRangeException - value is out of valid range 
            if (value < 0 || value > 999)
                throw new ArgumentOutOfRangeException(nameof(value),
                                                     "Id must between [000-999]");

            //DONE: we assign value to the field, not to the property
            m_ID = value;
        }
    }
...