In 4 years of C# soft engineering I have never encountered something like this. I thought Debugger's value inspect feature should not change inspected value's raw value, but I guess Debugger doesn't agree with that.
So, I have a rough idea why this might happen, and even found a similar case in Microsoft's C# forum, but not very sure of it. Also, when I returned newMsg and tried to call .ToArray() multiple times in a row, it gave different values to each call. My theory is, that every time I try to get IEnumerable's value, it does a recursive LINQ command, that in the process changes its datasource.
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);
}
Can someone explain if this is a real bug or is it intended to be like this.
One of the reasons of this problem may also be that without Reset()
enumerator cant work properly but there is a code under shows that you can reset enumerator by calling GetEnumerator()
again.
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
The debugger has to actually enumerate the newMsg
, which causes your code in SelectMany
to execute. The keyEnumerator
keeps being enumerated, never 'reset' between debugger's enumerations of newMsg
. That may lead to different results each time.
That's also why the user interface tells you that “Expanding the Results View will enumerate IEnumerable”. Unless it is a static collection, which is not in your case, the results will differ each time.