Expressions in C#
This topic applies to:
Visual Studio Edition |
Visual Basic |
C# |
C++ |
J# |
Express Edition |
No |
Yes |
No |
No |
Standard Edition |
No |
Yes |
No |
No |
Pro/Team Edition |
No |
Yes |
No |
No |
The managed expression evaluator accepts most expressions written in C#. The following sections offer specific information and discuss some of the expression types that are not supported:
Identifiers and Types
Method Evaluation
Operators
Overloaded Operators
Strings
Casts
typeof and sizeof Operators
Property Evaluation
The expression evaluator ignores access modifiers, public, protected, internal, and private. You can call a private method from the Watch window, for example. Because the expression evaluator ignores access modifiers, it is possible for an unexpected load to be invoked.
The expression evaluator performs all evaluations in an implicit unsafe context, whether the code being executed is safe or unsafe.
The expression evaluator also ignores checked blocks and the /checked compiler option. All expressions are evaluated in an unchecked context.
You can customize the display of custom data types using attributes. For more information, see Displaying Custom Data Types.
Identifiers and Types
Debugger expressions can use any identifier visible within the current scope. If the debugger is halted in method Magh
, for example, you can use any identifier visible within Magh
, including constants, variable names, and method names.
The debugger can correctly display any variable of a primitive, enum, or intrinsic type. For variables of class type, the debugger correctly displays the value based on the derived-most type. If you have an object leo
of type Lion
, derived from type Cat
, you can evaluate leo.Claws
and get the correct value for an object of type Lion
.
You can assign a new value to any left-hand expression that is an l-value. This includes primitive, class, and System.Object types.
Method Evaluation
The debugger supports the evaluation of methods, including overloaded methods. Therefore, you can enter either of the following expressions, and the debugger will call the correct version of the overloaded methods:
Time.Set();
Time.Set(atime);
Evaluating a method in the debugger actually calls and executes the code for that method. If the method has side effects, evaluating the method in a debugger window will change the state of your program, which can produce unexpected results.
When you set a breakpoint on an overloaded method, the location of the breakpoint depends on how you specify the method. If you specify the complete signature (method name and full argument list), the debugger sets one breakpoint on the specified overload. If you specify only the method name, the debugger's behavior depends on a Visual Studio options setting. If the Use IntelliSense to verify the function name checkbox is unchecked, the debugger will set one breakpoint on each overload of that method name. Otherwise the Choose Breakpoint dialog box will open, allowing you to specify which overload(s) to put the breakpoint on. For more information, see How to: Set a Function Breakpoint.
Creation of new anonymous methods is not supported in the debugger in this version of Visual Studio.
Operators
The debugger correctly evaluates most built-in operators, including:
Relational and equality operators: ( expr1
>
expr2, expr1<
expr2, expr1<=
expr2, expr1=>
expr2, expr1==
expr2, expr1!=
expr2).Boolean operators: (expr1
&&
expr2, expr1||
expr2, expr1?
expr2:
expr3).Arithmetical operators: (expr1
+
expr2, ** expr1-
expr2, expr1*
expr2, expr1/
expr2, expr1%
expr2 ).Logical operators: (expr1
&
expr2, expr1^
expr2, expr1|
expr2 ).Shift operators: (expr1
>>
expr2, expr1<<
expr2 ).Assignment operators: ( lvalue
=
expr2, lvalue*=
expr2 ** lvalue/=
expr2, lvalue%=
expr2, lvalue+=
expr2, lvalue-=
expr2, lvalue<<=
expr2, lvalue>>=
expr2, lvalue&=
expr2, lvalue^=
expr2, lvalue|=
expr2).Unary operators: (
+
expr1,-
expr1, expr1++
, ++expr1
, expr1--
,--
expr1).
Overloaded Operators
Most overloaded operators work in the debugger.
Overloaded infix operators +, -, /, %, and & work:
expr1
+
expr2expr1
expr1
/
expr2expr1
%
expr2expr1
&
expr2
Overloaded infix operators =, &&, &, and ||, do not work:
expr1
=
expr2expr1
&&
expr2expr1
&
expr2expr1
||
expr2
Overloaded infix operators << and >> do not work if both operands are class variables:
object1 <<object2
object1
>>
object2
Overloaded prefix operators +, -, ++, --, !, and ~ work:
+
expr1-
expr1++
expr1--
expr1!
expr1~
expr1
Overloaded suffix operators ++ and -- work:
expr1
++
expr1
--
Overloaded indexers work:
- expr1
[
expr2]
Strings
The debugger recognizes the indexed operator when it is used with strings as well as arrays. So, for example, you can enter:
"hello world"[0]
The Watch window will display the correct value:
'h'
In C#, unlike native C/C++, you can edit the value of a string in the debugger. In addition, you can use the Length
operator on a string:
mystring.Length
-or-
"hello world".Length
In C#, you can concatenate strings:
"hello" + "world"
Casts
Simple cast expressions work in the debugger:
(A)x
Casts that involve pointers will not work in the debugger.
typeof and sizeof Operators
The debugger supports the typeof
and sizeof
operator by transforming it into the equivalent .NET Framework function.
typeof (
expression )
is transformed into:
System.Type.GetType(
expression )
The debugger then evaluates this transformed expression.
The debugger supports the sizeof
operator.
Property Evaluation
The debugger can evaluate properties in any variable window. However, evaluating a property in the debugger can have side effects that produce unexpected and undesired results. To protect against side effects caused by accidental evaluation, you can turn property evaluation off in the Options dialog box.
WebMethods
You cannot call WebMethods from debugger windows.