如何正确清除包含结构的队列?

时间:2015-08-02 06:22:51

标签: c# struct queue

我已经宣布了一个像这样的基本结构

private struct ValLine {
  public string val;
  public ulong linenum;
}

并宣布像这样的队列

Queue<ValLine> check = new Queue<ValLine>();

然后在使用StreamReader设置中,我在while循环中使用ReadLine读取输入文件的行,除此之外,我这样做是为了填充队列:

check.Enqueue(new ValLine { val = line, linenum = linenum });

(&#34; line&#34;是一个包含每行文本的字符串,&#34; linenum&#34;只是一个初始化为0的计数器,每次循环都会递增。)< / p>

&#34;检查&#34;的目的队列是如果一条特定的线符合某些标准,那么我将该线存储在&#34;检查&#34;以及它在输入文件中出现的行号。

在我读完输入文件后,我使用&#34;检查&#34;对于各种各样的事情,但是当我使用它时,我以明显的方式清除它:

check.Clear();

(或者,在我的最终循环中#34;检查&#34;我可以使用.Dequeue(),而不是预先使用它。)

但后来我开始思考 - 等一下,所有这些&#34;新的ValLine&#34;我在第一时间填充队列时生成了???我创建了内存泄漏吗?我对C#很陌生,所以我不清楚如何处理这个 - 或者即使它应该被处理(也许.Clear()或.Dequeue()处理现在废弃的结构自动?)。我和我们亲爱的朋友谷歌花了一个多小时,并且没有找到关于清除结构集合的这种例子的具体讨论。

所以...在C#中,我们需要处理在清除队列之前消灭各个结构(或者在我们出队时),还是不行?如果是这样,那么这样做的正确方法是什么?

(以防它是相关的,我在Visual Studio 2013中使用.NET 4.5。)

更新:这是为了将来参考(你知道,就像这个页面出现在谷歌搜索中一样)关于正确的编码。为了使结构按照建议不可变,这就是我最终得到的结果:

private struct ValLine {
  private readonly string _val;
  private readonly ulong _linenum;
  public string val { get { return _val; } }
  public ulong linenum { get { return _linenum; } }
  public ValLine(string x, ulong n) { _val = x; _linenum = n; }
}

对应于该更改,队列填充行现在是:

check.Enqueue(new ValLine(line,linenum));

此外,虽然不是绝对必要,但我确实摆脱了队列中的foreach(以及check.Clear();,并将其更改为此

while (check.Count > 0) {
  ValLine ll = check.Dequeue();
  writer.WriteLine("[{0}] {1}", ll.linenum, ll.val);
}

以便在输出信息时清空队列。

更新2:好的,是的,我还是C#新手(不到一年)。我从互联网上学到了很多东西,但当然,我经常看一年多前的例子。我已经改变了我的结构,所以现在它看起来像这样:

private struct ValLine {
  public string val { get; private set; }
  public ulong linenum { get; private set; }
  public ValLine(string x, ulong n): this()
    { this.val = x; this.linenum = n; }
}

有趣的是,在第一次更新(上图)中提到了什么之前,我实际上已经尝试过这个问题,但是出现了编译错误(因为我没有{{1}使用构造函数)。根据进一步的建议,我进一步检查并找到一个最近的例子,显示: this()让它像我之前尝试的那样工作,将其插入,并且 - Wa La! - 清理编译。我喜欢代码的清洁外观。调用私有变量与我无关。

1 个答案:

答案 0 :(得分:1)

不,您不会创建内存泄漏。调用ClearDequeue会相应地清除内存 - 例如,如果您有List<T>,则可以使用明确的操作:

for (int i = 0; i < capacity; i++)
{
    array[i] = default(T);
}

我不知道Queue<T>是否使用构建在数组或链表上的循环缓冲区来实现 - 但不管怎样,你都没事。

话虽如此,我会强烈建议不要像你在这里一样使用可变结构,以及可变字段。虽然它没有引起您所设想的特定问题,但它们可能会以令人困惑的方式表现。