Решил сделать реализацию LinkedList
, используя IEnumerable
. Проблема как раз-таки в нем.
У меня есть метод Contains(..)
,где при использовании foreach исключений не возникает. Есть метод AddAfter(..)
, где исключение возникает.
Меня сбивают с толку две вещи:
Исключение возникает в цикле while(currentNode!=null) (но вылет происходит при currentNode==null)
Программа не вылетает при запуске без отладки, хотя в настройках исключений сказано "прерывать работу"
Вот эти функции:
public IEnumerator <T> GetEnumerator()
{
currentNode = firstNode;
while (currentNode != null)
{
yield return currentNode.Data;
currentNode = currentNode.Next;
}
}
public bool Contains(T item)
{
foreach (var t in this)
{
if (t.Equals(item))
return true;
}
return false;
}
public bool AddAfter(T item, T after)
{
if (this.Contains(item))
{
return false;
}
foreach (var t in this) // где-то здесь вылетает
{
if (t.Equals(after))
{
currentNode.Next = new Node <T>(item, currentNode, currentNode.Next);
if (currentNode == lastNode)
lastNode = lastNode.Next;
return true;
}
}
lastNode.Next = new Node <T>(item, lastNode, null);
lastNode = lastNode.Next;
return true;
}
Отладчик проходит Contains()
без вопросов, но на foreach
показывает проблему.
В режиме без отладки NullPointerException программу не останавливает(или просто не появляется), и она спокойно перешагивает foreach
, и появляются неверные данные.
Может, я как-то не правильно понимаю yield return
?
Я так понимаю, что при первом заходе в функцию выполнятся все строки до yield return
. При втором выполнится строка за yield
, и программа пойдет дальше по циклу. Тогда выходит, что currentNode между заходами обнуляется?
Вылет: Настройки исключений:
Это еще не все. Если запустить отладку, но при этом пошагово не заходить в этот проблемный foreach
, то, опять же, исключений не возникает, и программа выводит как раз-таки ожидаемые результаты. Но если при отладке зайди в этот foreach
, то будет исключение, как на втором скриншоте. Как это вообще работает?
Заполняю я весь этот список так:
var tb = TextField; // textBox
var list = new MyGenListUnique <int>();
list.AddRange(new []{0,1,2,3,4,5,6,7});
tb.AppendText(list.ToString() + Environment.NewLine);
list.AddAfter(-12, 2); // {0,1,2, -12, 3,4,5,6,7} // проблема здесь
tb.AppendText(list.ToString() + Environment.NewLine);
Вот функции добавления и связанные с ними:
public int AddRange(T[] items)
{
if (items is null)
{
return 0;
}
var countAdded = 0;
foreach (var t in items)
{
var currCount = Count;
Add(t);
if (currCount > Count)
countAdded++;
}
return countAdded;
}
public void Add(T item)
{
if (firstNode is null)
{
firstNode = new Node <T>(item, null, null);
lastNode = firstNode;
return ;
}
if (!this.Contains(item))
{
lastNode.Next = new Node <T>(item, lastNode, null);
lastNode = lastNode.Next;
IncreaseCount();
return ;
}
}
public new string ToString()
{
var sb = new StringBuilder(100);
sb.Append("{ ");
foreach (var t in this)
{
sb.Append(t + " ");
}
sb.Append("}");
return sb.ToString();
}
private void IncreaseCount(int count = 1)
{
Count += count;
}
Count
- autoproperty
, конструктор по умолчанию - пустой.
Если что, вот класс Node<T>
private class Node <T>
{
public T Data;
public Node <T> Next { get; set; }
public Node <T> Prev { get; set; }
public Node() {}
public Node(T data, Node <T> prev, Node <T> next)
{
Data = data;
Next = next;
Prev = prev;
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Одна задача, ожидает выполнение другой задачи, как только возвращаем null из ожидаемой задачи, происходит прерывание выполнения другой
Как отправить в C# hex а не string на tcp? Использую для проверки програму-клиент-сервер и если конвертировать string в байты то эта программа получит...