Rob Levine
Rob Levine

Reputation: 41338

Conditional breakpoints and watch window do not short-circuit expression evaluation

[EDIT - changed example to avoid confusion about the root issue]

While trying to work out why my conditional breakpoints keep generating errors in Visual Studio, I've stumbled across a behaviour I did not expect.

In the watch window, immediate window, or as the condition of a breakpoint, Visual Studio does not appear to short-circuit expression evaluation.

For example, stopping at a breakpoint on the line after this:

string obj = "hello";

and evaluating the following in the watch window

obj is int && ((int)obj) == 1

should give the result

false

but instead gives

CS0030: Cannot convert type 'string' to 'int'

This prevents me from doing things like checking the type of an object, and then casting to that type and checking a property in my conditional breakpoints, which seriously reduces their usefulness.

Do other people see this behaviour, and does anyone know how to make conditional breakpoints/watch window short-circuit?

The one less-than-ideal workaround that I've come up with is to wrap the expression in a method in your code, and evaluate this from the watch window. However, this involves changing code and recompiling, instead of being able to dynamically change conditions while debugging.

Upvotes: 3

Views: 248

Answers (2)

user7740635
user7740635

Reputation: 46

I had the same issue trying to break on a generic property setter with value type object

(propertyName=="xxx") && (value is int) && ((int)value==5000)

Replacing the second && with a ?: operator seems to do the trick

(propertyName=="xxx") && ((value is int) ? ((int)value==5000) : false)

Upvotes: 1

Manfred Radlwimmer
Manfred Radlwimmer

Reputation: 13394

Actually this statement wouldn't work in the immediate window or in code either because the compiler knows obj will never be castable to int.

If you had defined obj as an object it would work as expected.

object obj = "hello";
bool result = obj is int && ((int)obj) == 1;

The code above will compile and work as a breakpoint condition.

As leppie mentioned you could re-cast your object ((int)(object) obj) to avoid this, but that should always be a measure of last resort.

Upvotes: 3

Related Questions