Необработанное исключение. System.NullReferenceException: ссылка на объект не указывает на экземпляр объекта

Я пытаюсь распечатать содержимое стека.

Класс стека

Когда я делаю попытку, я получаю следующую ошибку.

Необработанное исключение. System.NullReferenceException: ссылка на объект не указывает на экземпляр объекта.

Что происходит в строке foreach моего кода. Я не уверен, почему это происходит, так как я думал, что использую пример, приведенный на странице, на которую я ссылаюсь. Примером будет...

        foreach( string number in numbers )
        {
            Console.WriteLine(number);
        }

Ниже приведен мой код. Кажется, все работает, кроме этой части, которая выдает ошибку.

            foreach(var s in stack)
            {
                Console.WriteLine(s);
            }

... и это мой код.

using System;

namespace Exercise
{
    class Program
    {
        static void Main()
        {
            var stack = new Stack();
            stack.Push(1);
            stack.Push(2);
            stack.Push(3);

            foreach(var s in stack)
            {
                Console.WriteLine(s);
            }
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Exercise
{
    internal class Stack : IEnumerable
    {
        private object _object;
        private List<object> list = new List<object>();
        private IEnumerator Enumerator;
        public IEnumerator GetEnumerator() => Enumerator;

        internal object Pop()
        {
            if (list.Count == 0)
                throw new InvalidOperationException("Cannot use .Pop() if list count equals 0.");

            _object = list.FirstOrDefault();

            list.RemoveAt(0);

            return _object;
        }

        internal void Push(object obj)
        {
            _object = obj;

            if (_object == null)
                throw new InvalidOperationException("Cannot use .Push() if object is null.");

            list.Insert(0, _object);
        }

        internal void Clear()
        {
            if (list.Count == 0)
                throw new InvalidOperationException("Cannot use .Clear() if list is empty.");

            list.Clear();
        }
    }
}

Что я делаю неправильно и как это исправить, чтобы распечатать содержимое стека?


person Milliorn    schedule 31.03.2020    source источник


Ответы (1)


Ваш метод GetEnumerator возвращает значение null, поскольку поле Enumerator никогда не было явно инициализировано, поэтому оно получило значение по умолчанию null.

Затем цикл foreach вызывает .GetEnumerator(), получает значение NULL и пытается получить доступ к свойству .Current значения NULL, поэтому вы получаете NullReferenceExcpetion.

Чтобы исправить это, вы можете использовать следующую реализацию:

public IEnumerator GetEnumerator()
{
    while (list.Any())
        yield return Pop();
}
person Gur Galler    schedule 31.03.2020
comment
Мне нравится ваше решение, но оно не перечисляет всю коллекцию, потому что вы увеличиваете i по мере уменьшения list.Count. В этом примере, когда list.Count равно 1, i равно 2, и цикл for заканчивается. Вместо этого используйте while (list.Any()). - person rfmodulator; 31.03.2020
comment
Спасибо Гур Галлер за это. Это было то, чего мне не хватало. Также спасибо @rfmodulator за упоминание об исправлении кода Gur Galler. Теперь все работает. - person Milliorn; 31.03.2020