【问题标题】:C# - IEnumerable<> StackOverFlowException (AVLTree)C# - IEnumerable<> StackOverFlowException (AVLTree)
【发布时间】:2017-02-15 21:26:30
【问题描述】:

我在使用 IEnumerable&lt;&gt; 时遇到问题

我正在读取一个 CSV 文件,我已经对我的 get/set 方法进行了排序,并且我在实现 IEnumerable&lt;&gt; 之前测试了我的代码,并且 Autos/Locals 显示正确。

我正在尝试在 DataGridView 中显示 CSV 文件的内容

foreach (Country country in avlTree)
                    {

                      displayCountriesDataGridView.Rows.Add(country.CountryName, country.GDPGrowth, country.Inflation, country.TradeBalance, country.HDIRank, country.TradingPartners);

                    }

并使用我编写的 AVLTree 和 InsertItem 方法将此数据附加到 AVLTree

  avlTree.InsertItem(tempCountry);

当我使用时出现这个问题:

class AVLTree<T> : BSTree<T>, IEnumerable<Country> where T : IComparable

我已经实现了接口:

 public IEnumerator<Country> GetEnumerator()
        {

            return this.GetEnumerator();

            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {

            return GetEnumerator();
            throw new NotImplementedException();
        }


    }

但是,从来没有运气。

在本地,我得到了这个输出-

$exception {"Exception of type "System.StackOverflowException' was thrown"}

我得到一个红十字和名称this,其值为Unable to read memory

Type Variables T 的值为System.__Canon

我在 Country 类中实现了 IEnumerable&lt;&gt;,没有任何问题。

我似乎无法理解导致此问题的原因。

有人可以提供一些指导或阐明这个问题。

谢谢。

编辑 - 我的 AVLTree 的实现

   class AVLTree<T> : BSTree<T>, IEnumerable<Country> where T : IComparable
    {

        Node<T> newRoot;



        public new void InsertItem(T item)
        {
            insertItem(item, ref root);
        }



        private void insertItem(T item, ref Node<T> tree)
        {
            if (tree == null)
            {
                tree = new Node<T>(item);
            }

            else if (item.CompareTo(tree.Data) < 0)
            {
                insertItem(item, ref tree.Left);
            }
            else if (item.CompareTo(tree.Data) > 0)
            {
                insertItem(item, ref tree.Right);
            }

            tree.BalanceFactor = Height(ref tree.Left) - Height(ref tree.Right);

            if (tree.BalanceFactor <= -2)
            {
                rotateLeft(ref tree);
            }
            if (tree.BalanceFactor >= 2)
            {
                rotateRight(ref tree);
            }
        }




        private void rotateRight(ref Node<T> tree)
        {
            if (tree.Left.BalanceFactor < 0)
            {
                rotateLeft(ref tree.Left);
            }
            newRoot = tree.Left;
            tree.Left = newRoot.Right;
            newRoot.Right = tree;
            tree = newRoot;

        }


        private void rotateLeft(ref Node<T> tree)
        {
            if (tree.Right.BalanceFactor > 0)
            {
                rotateRight(ref tree.Right);
            }

            newRoot = tree.Right;
            tree.Right = newRoot.Left;
            newRoot.Left = tree;
            tree = newRoot;

        }

        public IEnumerator<Country> GetEnumerator()
        {
            // Some iterator/loop which uses "yield return" for each item

        }


        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

【问题讨论】:

  • 设置断点,单步执行代码?您的方法正在调用自己。为什么要实现IEnumerable&lt;T&gt;BSTree&lt;T&gt; 是什么?
  • @CodeCaster 这是另一个类,我有一个 BSTree、BinaryTree 和 AVLTree 以及一个具有 Left、Right、T Data 和 BalanceFactor getter/setter 的 Node 类。
  • 您的 GetEnumerator 一直在调用自己。它当然会导致堆栈溢出。调试器会立即显示此问题。
  • @SamiKuhmonen 如何消除这个循环?
  • GetEnumerator 只会调用自身导致异常。如果你已经在你的基类中实现了它,你应该可以删除这个版本。

标签: c# ienumerable avl-tree


【解决方案1】:

您需要实际实现一个枚举器。现在你的实现通过调用自身无限循环——没有返回枚举数。

public IEnumerator<Country> GetEnumerator()
{
    // Some iterator/loop which uses "yield return" for each item
    foreach (var item in items)
        yield return item;
}

IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

【讨论】:

  • 您好,感谢您的回答。我的错误越来越明显。只是一个问题 它不是应该是foreach,而不是var item,难道不是Country item吗?我从来没有用过这个。我也在为in (?) 苦苦挣扎。我只有Node&lt;T&gt;rotateLeftrotateRightinsertItem。在我的 AVLTree 课程中。
  • 是的。 Country itemvar item 意思相同。你可以编写任何你喜欢的 for/foreach/while 循环。重要的部分是yield return每个项目。 dotnetperls.com/yield
  • 我只是在努力理解in (...)。我应该放什么? foreach (Country item in ... ).
  • 你能发布一些关于你通常如何行走你的树的代码吗?然后我可以根据您的使用情况调整答案。
  • 因此,您希望如何走树的逻辑尚不清楚。这不是一个简单的线性流。您是否希望列出所有分支上的每个项目?你希望走一根树枝吗?你是从树干走到叶子还是从叶子到树干?您可能需要设计迭代流程,然后您就可以轻松编写代码了。
猜你喜欢
  • 2013-12-08
  • 1970-01-01
  • 2021-03-03
  • 2011-01-02
  • 2015-03-25
  • 2021-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多