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

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

**关闭。**此题需要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命令,在此过程中会更改其数据源。

public IEnumerable<byte> Shift(IEnumerable<byte> msg)
{
    var parts = msg.Chunk(blockLength);
    var keyEnumerator = shifter.GetEnumerator();
    var newMsg = parts.SelectMany(part =>
    {
        if (!keyEnumerator.MoveNext())
        {
            keyEnumerator = shifter.GetEnumerator();
            //keyEnumerator.Reset();
            keyEnumerator.MoveNext();
        }
        byte shift = (byte)(keyEnumerator.Current % blockLength);
        var res = part.TakeLast(blockLength - shift).Concat(part.Take(shift));
        //Debug.Write(string.Join('-', res.Select(i => $"{i:X2}")) + "-");
        return res;
    });

    return TextManipualtion.UnPadByteIEnumerable(newMsg);
}

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

IEnumerable<int> ints = Enumerable.Range(0, 5);
var atro = ints.GetEnumerator();
for (int i = 0; i < 2; i++)
{
    atro.MoveNext();
    Console.WriteLine(atro.Current);
}

atro = ints.GetEnumerator();
for (int i = 0; i < 4; i++)
{
    atro.MoveNext();
    Console.WriteLine(atro.Current);
}

//Output
//0
//1
//0
//1
//2
//3
qnakjoqk

qnakjoqk1#

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

相关问题