Currently we only allow setting breakpoints on sequence points and those are limited to IL offsets where the evaluation stack is empty.
As C# gets more expression oriented it would be very useful to be able to place breakpoint on an arbitrary expression.Implementing such a feature is certainly not gonna be cheap as it might require changes across many layers and components.
UPDATE: Turns out we were able to find out an inexpensive technique how to achieve this.
:memo: Related to #21781.
Permitting breakpoints in the when clause and expression parts of a switch expression is a fairly simple change.
馃挴
Without the ability to set breakpoints developers will be shunning expressions. We already see expressions being undone because they make debugging so much harder.
I've avoided object initializer in the past already because they destroy line numbers in stacktraces, expression switch cases make this so much worse, i've basically banned them for anything that does a method call or could possible generate an exception. I hope this is adressed very soon.
Addressed in https://github.com/dotnet/roslyn/pull/42711
Is there a summary of where to expect the additional sequence points to show up? So far I know about switch expressions. Does it go as far as conditional expressions, object initializers, &&
operators, etc? Will 'step over'/'step in' apply to nested expressions?
Currently only switch expressions. We will need to discuss what other expressions we want to support because for other expressions it will degrade code quality. For the debugging experience, the parts of the expression will act just like statements.
One side benefit of more granular expression sequence points is that code coverage tools will begin to recognize conditional expressions and short-circuiting operators as branches. Many (all?) of them depend on debugger sequence points because that's the only mapping from IL to source code.
There are two distinct things I'd really love:
&&
or a recursive patternIs https://github.com/dotnet/roslyn/issues/21781 the issue to follow for both of these?
Recursive patterns are not expressions. Order of evaluation is not guaranteed, and in a switch the order is nonlinear (we don't re-evaluate patterns that were previously evaluated for other branches). I do not expect sequence points within patterns.
The other places we can do, at the cost of reduced code quality. I don't know yet which ones we actually will do.
Thanks. Should I file an issue or multiple issues for the ones I want to follow (conditional expression, &&
, ||
, ??
), or is there already an issue to follow?
@jnm2 Yes, please. I think for those expressions a single issue would make sense. The other one we are considering is object initializers, but we don't have an issue tracking that yet.
@gafter Opened https://github.com/dotnet/roslyn/issues/43092. Should I open an issue for object initializers too?
Actually, would https://github.com/dotnet/roslyn/issues/27184 be the issue for object initializers now?
@jnm2 Sure, though it would be better if #27184 actually had a description of what it is asking for.
@gafter Is there any point in me generating such a description, or do you have an idea of how you'd like it to be either way?
@jnm2 It would be great if you would please write a description suitable for the issue asking for breakpoints inside object initializers for #27184.
Most helpful comment
Addressed in https://github.com/dotnet/roslyn/pull/42711