.net 每次< T>我在VS2022的调试模式下尝试检查IEnumerable时,它的值都会发生变化,

bxgwgixi  于 2023-07-01  发布在  .NET
关注(0)|答案(1)|浏览(171)

**关闭。**此题需要debugging details。目前不接受答复。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答这个问题。
6小时前关闭
截至3小时前,社区正在审查是否重新开放此问题。
Improve this question
在4年的C#软件工程中,我从来没有遇到过像this这样的东西。我认为调试器的值检查功能不应该改变检查值的原始值,但我猜调试器不同意这一点。
所以,我大概知道为什么会发生这种情况,甚至在微软的C#论坛上发现了一个类似的case,但不是很确定。此外,当我返回newMsg并尝试连续多次调用.ToArray()时,它为每次调用提供了不同的值。我的理论是,每次我试图获取IEnumerable的值时,它都会执行一个递归的LINQ命令,在此过程中会更改其数据源。

  1. public IEnumerable<byte> Shift(IEnumerable<byte> msg)
  2. {
  3. var parts = msg.Chunk(blockLength);
  4. var keyEnumerator = shifter.GetEnumerator();
  5. var newMsg = parts.SelectMany(part =>
  6. {
  7. if (!keyEnumerator.MoveNext())
  8. {
  9. keyEnumerator = shifter.GetEnumerator();
  10. //keyEnumerator.Reset();
  11. keyEnumerator.MoveNext();
  12. }
  13. byte shift = (byte)(keyEnumerator.Current % blockLength);
  14. var res = part.TakeLast(blockLength - shift).Concat(part.Take(shift));
  15. //Debug.Write(string.Join('-', res.Select(i => $"{i:X2}")) + "-");
  16. return res;
  17. });
  18. return TextManipualtion.UnPadByteIEnumerable(newMsg);
  19. }

有人能解释一下这是一个真实的的bug还是故意这样的。
这个问题的原因之一也可能是没有Reset()枚举器不能正常工作,但下面有一段代码显示,你可以通过再次调用GetEnumerator()来重置枚举器。

  1. IEnumerable<int> ints = Enumerable.Range(0, 5);
  2. var atro = ints.GetEnumerator();
  3. for (int i = 0; i < 2; i++)
  4. {
  5. atro.MoveNext();
  6. Console.WriteLine(atro.Current);
  7. }
  8. atro = ints.GetEnumerator();
  9. for (int i = 0; i < 4; i++)
  10. {
  11. atro.MoveNext();
  12. Console.WriteLine(atro.Current);
  13. }
  14. //Output
  15. //0
  16. //1
  17. //0
  18. //1
  19. //2
  20. //3
qnakjoqk

qnakjoqk1#

调试器必须实际枚举newMsg,这将导致执行SelectMany中的代码。keyEnumerator保持被枚举,在调试器的newMsg枚举之间从不“重置”。这可能会导致每次不同的结果。
这也是为什么用户界面告诉您 “展开结果视图将枚举IEnumerable”。除非它是一个静态集合(在您的情况下不是),否则每次的结果都会有所不同。

相关问题