Before the line with the -->, the changedRows is null, as it should be. It then goes out of scope, as you get the next work item. You then come back in, and before the line with the --> if you access changedRows, it should be again null, as it hasn't be declared.

If you break and edit, then, as you expect, you can't access changedRows, because it's gone out of scope, and not been declared yet. If you evaluate it (either by mouseover or using the immediate window), you have access to the changedRows from the previous iteration of the loop. WTH?

Anyone seen this? It doesn't affect the program as it seems to act correctly in code, but the debugger issue caused a waste of time since it wasn't behaving as expected.

I don't know enough to answer the question at the language level, but as I'm sure you know, block scope and object lifetime don't have much to do with eachother in .NET. So it's perfectly valid for the object to be alive - perhaps it's even because of the debugger holding a reference it's not getting GC'ed?

But I'd definitely not expect the debugger to show the variable in 'locals' before it's in scope (the same goes for 'watch') - but perhaps there's something tricky about .NET variable scope?

You might want to make a StackOverflow post on this and hope John Skeet or somebody can come up with a good answer - and if you do, please post a link here.

Someone answered it, and the answer does seem feasible, even though it's mind-boggling.

The really squirrelly thing that's bothering me is the fact that in the code (break and edit) the object shows as null, and you can't access any of the properties via intellisense. But in the watch window and in the immediate window, you can access all of the properties, and it's of the object that's gone out of scope. It didn't cause any problems because I was declaring/instantiating it later in the scope, but that shows me that there's *something* weird about it because if it was actually declared the compiler would have complained about the re-declaration.

No, it was a debug build, with optimization turned off. It makes sense that to do some of the things that the debugger does, it violates the rules of the compiler, though I never really thought about it in that manner.

Nit-picking: the language rules don't say the object must be destroyed when it goes out of scope - but when there's no more references to it. And because .NET uses a tracing GC, it furthermore doesn't guarantee this happens as soon as the last reference is removed, but "at whatever time the systems believes it's right to take out the trash".

This is why finalizers in C# are pretty much useless for anything but "Uh oh, moron, you forgot to Dispose" diagnostics