RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 779734
Accepted
Victor Gorban
Victor Gorban
Asked:2020-02-03 22:27:53 +0000 UTC2020-02-03 22:27:53 +0000 UTC 2020-02-03 22:27:53 +0000 UTC

while(!=null) IEnumerator 中的 NullPointerException

  • 772

决定LinkedList使用IEnumerable. 问题就在其中。我有一个方法Contains(..),在使用 foreach 时不会引发异常。有一个AddAfter(..)抛出异常的方法。有两件事让我感到困惑:

  1. 在 while(currentNode!=null) 循环中发生异常(但在 currentNode==null 处发生崩溃)

  2. 即使异常设置说“中止”,程序也不会在没有调试的情况下在启动时崩溃

这些是功能:

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;
    }  
}
c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Pavel Mayorov
    2020-03-18T20:08:08Z2020-03-18T20:08:08Z

    这里的一切都很简单。您的调用在每次调用中GetEnumerator()使用相同的变量currentNode,这是一个错误,因为不同的枚举数必须是独立的。

    在没有调试器的情况下运行时,这不起作用,因为您不会GetEnumerator多次调用。

    但是当您在调试器下运行时,调试器本身会调用GetEnumerator()以显示变量的值this。更准确地说,是演播室电话ToString(),你已经打通了GetEnumerator()——但电话GetEnumerator()也可以想象。

    public因此,道德:编写较少混淆的代码,并始终准备好让某人调用声明为方法的方法。

    具体来说,在您的代码中,要修复错误,您需要将其设为currentNode局部变量。并用这个替换循环foreach (var t in this):

    for (var currentNode = firstNode; currentNode != null; currentNode = currentNode.Next) 
    {
        // ...
    }
    
    • 2
  2. Victor Gorban
    2020-02-18T17:24:13Z2020-02-18T17:24:13Z

    好吧,我在项目属性中关闭了优化。打开它 - 一切都很好,调试期间的行为对应于没有调试的行为。不幸的是,这可能很重要。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5