
- •Language Specification
- •Version 4.0
- •1. Introduction 1
- •2. Lexical structure 37
- •3. Basic concepts 59
- •4. Types 83
- •5. Variables 99
- •6. Conversions 115
- •7. Expressions 137
- •8. Statements 239
- •9. Namespaces 268
- •10. Classes 279
- •11. Structs 376
- •12. Arrays 389
- •12.1 Array types 389
- •13. Interfaces 395
- •18. Unsafe code 443
- •1.Introduction
- •1.1Hello world
- •1.2Program structure
- •1.3Types and variables
- •1.4Expressions
- •1.5Statements
- •1.6Classes and objects
- •1.6.1Members
- •1.6.2Accessibility
- •1.6.3Type parameters
- •1.6.4Base classes
- •1.6.5Fields
- •1.6.6Methods
- •1.6.6.1Parameters
- •1.6.6.2Method body and local variables
- •1.6.6.3Static and instance methods
- •1.6.6.4Virtual, override, and abstract methods
- •1.6.6.5Method overloading
- •1.6.7Other function members
- •1.6.7.1Constructors
- •1.6.7.2Properties
- •1.6.7.3Indexers
- •1.6.7.4Events
- •1.6.7.5Operators
- •1.6.7.6Destructors
- •1.7Structs
- •1.8Arrays
- •1.9Interfaces
- •1.10Enums
- •1.11Delegates
- •1.12Attributes
- •2.Lexical structure
- •2.1Programs
- •2.2Grammars
- •2.2.1Grammar notation
- •2.2.2Lexical grammar
- •2.2.3Syntactic grammar
- •2.3Lexical analysis
- •2.3.1Line terminators
- •2.3.2Comments
- •2.3.3White space
- •2.4Tokens
- •2.4.1Unicode character escape sequences
- •2.4.2Identifiers
- •2.4.3Keywords
- •2.4.4Literals
- •2.4.4.1Boolean literals
- •2.4.4.2Integer literals
- •2.4.4.3Real literals
- •2.4.4.4Character literals
- •2.4.4.5String literals
- •2.4.4.6The null literal
- •2.4.5Operators and punctuators
- •2.5Pre-processing directives
- •2.5.1Conditional compilation symbols
- •2.5.2Pre-processing expressions
- •2.5.3Declaration directives
- •2.5.4Conditional compilation directives
- •2.5.5Diagnostic directives
- •2.5.6Region directives
- •2.5.7Line directives
- •2.5.8Pragma directives
- •2.5.8.1Pragma warning
- •3.Basic concepts
- •3.1Application Startup
- •3.2Application termination
- •3.3Declarations
- •3.4Members
- •3.4.1Namespace members
- •3.4.2Struct members
- •3.4.3Enumeration members
- •3.4.4Class members
- •3.5.1Declared accessibility
- •3.5.2Accessibility domains
- •3.5.3Protected access for instance members
- •3.5.4Accessibility constraints
- •3.6Signatures and overloading
- •3.7Scopes
- •3.7.1Name hiding
- •3.7.1.1Hiding through nesting
- •3.7.1.2Hiding through inheritance
- •3.8Namespace and type names
- •3.8.1Fully qualified names
- •3.9Automatic memory management
- •3.10Execution order
- •4.Types
- •4.1Value types
- •4.1.1The System.ValueType type
- •4.1.2Default constructors
- •4.1.3Struct types
- •4.1.4Simple types
- •4.1.5Integral types
- •4.1.6Floating point types
- •4.1.7The decimal type
- •4.1.8The bool type
- •4.1.9Enumeration types
- •4.1.10Nullable types
- •4.2Reference types
- •4.2.1Class types
- •4.2.2The object type
- •4.2.3The dynamic type
- •4.3Boxing and unboxing
- •4.3.1Boxing conversions
- •4.3.2Unboxing conversions
- •4.4Constructed types
- •4.4.1Type arguments
- •4.4.2Open and closed types
- •4.4.3Bound and unbound types
- •4.4.4Satisfying constraints
- •4.5Type parameters
- •4.6Expression tree types
- •4.7The dynamic type
- •5.Variables
- •5.1Variable categories
- •5.1.1Static variables
- •5.1.2Instance variables
- •5.1.2.1Instance variables in classes
- •5.1.2.2Instance variables in structs
- •5.1.3Array elements
- •5.1.4Value parameters
- •5.1.5Reference parameters
- •5.1.6Output parameters
- •5.1.7Local variables
- •5.2Default values
- •5.3Definite assignment
- •5.3.1Initially assigned variables
- •Value parameters.
- •5.3.2Initially unassigned variables
- •5.3.3Precise rules for determining definite assignment
- •5.3.3.1General rules for statements
- •5.3.3.2Block statements, checked, and unchecked statements
- •5.3.3.3Expression statements
- •5.3.3.4Declaration statements
- •5.3.3.5If statements
- •5.3.3.6Switch statements
- •5.3.3.7While statements
- •5.3.3.8Do statements
- •5.3.3.9For statements
- •5.3.3.10Break, continue, and goto statements
- •5.3.3.11Throw statements
- •5.3.3.12Return statements
- •5.3.3.13Try-catch statements
- •5.3.3.14Try-finally statements
- •5.3.3.15Try-catch-finally statements
- •5.3.3.21General rules for expressions with embedded expressions
- •5.3.3.22Invocation expressions and object creation expressions
- •5.3.3.23Simple assignment expressions
- •5.3.3.24&& Expressions
- •5.3.3.25|| Expressions
- •5.3.3.26! Expressions
- •5.3.3.27?? Expressions
- •5.3.3.28?: Expressions
- •5.3.3.29Anonymous functions
- •5.4Variable references
- •5.5Atomicity of variable references
- •6.Conversions
- •6.1Implicit conversions
- •6.1.1Identity conversion
- •6.1.2Implicit numeric conversions
- •6.1.3Implicit enumeration conversions
- •6.1.4Implicit nullable conversions
- •6.1.5Null literal conversions
- •6.1.6Implicit reference conversions
- •6.1.7Boxing conversions
- •6.1.8Implicit dynamic conversions
- •6.1.9Implicit constant expression conversions
- •6.1.10Implicit conversions involving type parameters
- •6.1.11User-defined implicit conversions
- •6.1.12Anonymous function conversions and method group conversions
- •6.2Explicit conversions
- •6.2.1Explicit numeric conversions
- •6.2.2Explicit enumeration conversions
- •6.2.3Explicit nullable conversions
- •6.2.4Explicit reference conversions
- •6.2.5Unboxing conversions
- •6.2.6Explicit dynamic conversions
- •6.2.7Explicit conversions involving type parameters
- •6.2.8User-defined explicit conversions
- •6.3Standard conversions
- •6.3.1Standard implicit conversions
- •6.3.2Standard explicit conversions
- •6.4User-defined conversions
- •6.4.1Permitted user-defined conversions
- •6.4.2Lifted conversion operators
- •6.4.3Evaluation of user-defined conversions
- •6.4.4User-defined implicit conversions
- •6.4.5User-defined explicit conversions
- •6.5Anonymous function conversions
- •6.5.1Evaluation of anonymous function conversions to delegate types
- •6.5.2Evaluation of anonymous function conversions to expression tree types
- •6.5.3Implementation example
- •6.6Method group conversions
- •7.Expressions
- •7.1Expression classifications
- •7.1.1Values of expressions
- •7.2Static and Dynamic Binding
- •7.2.1Binding-time
- •7.2.2Dynamic binding
- •7.2.3Types of constituent expressions
- •7.3Operators
- •7.3.1Operator precedence and associativity
- •7.3.2Operator overloading
- •7.3.3Unary operator overload resolution
- •7.3.4Binary operator overload resolution
- •7.3.5Candidate user-defined operators
- •7.3.6Numeric promotions
- •7.3.6.1Unary numeric promotions
- •7.3.6.2Binary numeric promotions
- •7.3.7Lifted operators
- •7.4Member lookup
- •7.4.1Base types
- •7.5Function members
- •Indexers
- •Instance constructors
- •7.5.1Argument lists
- •7.5.1.1Corresponding parameters
- •7.5.1.2Run-time evaluation of argument lists
- •7.5.2Type inference
- •7.5.2.1The first phase
- •7.5.2.2The second phase
- •7.5.2.7Explicit parameter type inferences
- •7.5.2.8Exact inferences
- •7.5.2.9Lower-bound inferences
- •7.5.2.10Upper-bound inferences
- •7.5.2.11Fixing
- •7.5.2.12Inferred return type
- •7.5.2.13Type inference for conversion of method groups
- •7.5.2.14Finding the best common type of a set of expressions
- •7.5.3Overload resolution
- •7.5.3.1Applicable function member
- •7.5.3.2Better function member
- •7.5.3.3Better conversion from expression
- •7.5.3.4Better conversion from type
- •7.5.3.5Better conversion target
- •7.5.3.6Overloading in generic classes
- •7.5.4Compile-time checking of dynamic overload resolution
- •7.5.5Function member invocation
- •7.5.5.1Invocations on boxed instances
- •7.6Primary expressions
- •7.6.1Literals
- •7.6.2Simple names
- •7.6.2.1Invariant meaning in blocks
- •7.6.3Parenthesized expressions
- •7.6.4Member access
- •7.6.4.1Identical simple names and type names
- •7.6.4.2Grammar ambiguities
- •7.6.5Invocation expressions
- •7.6.5.1Method invocations
- •7.6.5.2Extension method invocations
- •7.6.5.3Delegate invocations
- •7.6.6Element access
- •7.6.6.1Array access
- •7.6.6.2Indexer access
- •7.6.7This access
- •7.6.8Base access
- •7.6.9Postfix increment and decrement operators
- •7.6.10The new operator
- •7.6.10.1Object creation expressions
- •7.6.10.2Object initializers
- •7.6.10.3Collection initializers
- •7.6.10.4Array creation expressions
- •7.6.10.5Delegate creation expressions
- •7.6.10.6Anonymous object creation expressions
- •7.6.11The typeof operator
- •7.6.12The checked and unchecked operators
- •7.6.13Default value expressions
- •7.6.14Anonymous method expressions
- •7.7Unary operators
- •7.7.1Unary plus operator
- •7.7.2Unary minus operator
- •7.7.3Logical negation operator
- •7.7.4Bitwise complement operator
- •7.7.5Prefix increment and decrement operators
- •7.7.6Cast expressions
- •7.8Arithmetic operators
- •7.8.1Multiplication operator
- •7.8.2Division operator
- •7.8.3Remainder operator
- •7.8.4Addition operator
- •7.8.5Subtraction operator
- •7.9Shift operators
- •7.10Relational and type-testing operators
- •7.10.1Integer comparison operators
- •7.10.2Floating-point comparison operators
- •7.10.3Decimal comparison operators
- •7.10.4Boolean equality operators
- •7.10.5Enumeration comparison operators
- •7.10.6Reference type equality operators
- •7.10.7String equality operators
- •7.10.8Delegate equality operators
- •7.10.9Equality operators and null
- •7.10.10The is operator
- •7.10.11The as operator
- •7.11Logical operators
- •7.11.1Integer logical operators
- •7.11.2Enumeration logical operators
- •7.11.3Boolean logical operators
- •7.11.4Nullable boolean logical operators
- •7.12Conditional logical operators
- •7.12.1Boolean conditional logical operators
- •7.12.2User-defined conditional logical operators
- •7.13The null coalescing operator
- •7.14Conditional operator
- •7.15Anonymous function expressions
- •7.15.1Anonymous function signatures
- •7.15.2Anonymous function bodies
- •7.15.3Overload resolution
- •7.15.4Anonymous functions and dynamic binding
- •7.15.5Outer variables
- •7.15.5.1Captured outer variables
- •7.15.5.2Instantiation of local variables
- •7.15.6Evaluation of anonymous function expressions
- •7.16Query expressions
- •7.16.1Ambiguities in query expressions
- •7.16.2Query expression translation
- •7.16.2.1Select and groupby clauses with continuations
- •7.16.2.2Explicit range variable types
- •7.16.2.3Degenerate query expressions
- •7.16.2.4From, let, where, join and orderby clauses
- •7.16.2.5Select clauses
- •7.16.2.6Groupby clauses
- •7.16.2.7Transparent identifiers
- •7.16.3The query expression pattern
- •7.17Assignment operators
- •7.17.1Simple assignment
- •7.17.2Compound assignment
- •7.17.3Event assignment
- •7.18Expression
- •7.19Constant expressions
- •7.20Boolean expressions
- •8.Statements
- •8.1End points and reachability
- •8.2Blocks
- •8.2.1Statement lists
- •8.3The empty statement
- •8.4Labeled statements
- •8.5Declaration statements
- •8.5.1Local variable declarations
- •8.5.2Local constant declarations
- •8.6Expression statements
- •8.7Selection statements
- •8.7.1The if statement
- •8.7.2The switch statement
- •8.8Iteration statements
- •8.8.1The while statement
- •8.8.2The do statement
- •8.8.3The for statement
- •8.8.4The foreach statement
- •8.9Jump statements
- •8.9.1The break statement
- •8.9.2The continue statement
- •8.9.3The goto statement
- •8.9.4The return statement
- •8.9.5The throw statement
- •8.10The try statement
- •8.11The checked and unchecked statements
- •8.12The lock statement
- •8.13The using statement
- •8.14The yield statement
- •9.Namespaces
- •9.1Compilation units
- •9.2Namespace declarations
- •9.3Extern aliases
- •9.4Using directives
- •9.4.1Using alias directives
- •9.4.2Using namespace directives
- •9.5Namespace members
- •9.6Type declarations
- •9.7Namespace alias qualifiers
- •9.7.1Uniqueness of aliases
- •10.Classes
- •10.1Class declarations
- •10.1.1Class modifiers
- •10.1.1.1Abstract classes
- •10.1.1.2Sealed classes
- •10.1.1.3Static classes
- •10.1.1.3.1Referencing static class types
- •10.1.2Partial modifier
- •10.1.3Type parameters
- •10.1.4Class base specification
- •10.1.4.1Base classes
- •10.1.4.2Interface implementations
- •10.1.5Type parameter constraints
- •10.1.6Class body
- •10.2Partial types
- •10.2.1Attributes
- •10.2.2Modifiers
- •10.2.3Type parameters and constraints
- •10.2.4Base class
- •10.2.5Base interfaces
- •10.2.6Members
- •10.2.7Partial methods
- •10.2.8Name binding
- •10.3Class members
- •10.3.1The instance type
- •10.3.2Members of constructed types
- •10.3.3Inheritance
- •10.3.4The new modifier
- •10.3.5Access modifiers
- •10.3.6Constituent types
- •10.3.7Static and instance members
- •10.3.8Nested types
- •10.3.8.1Fully qualified name
- •10.3.8.2Declared accessibility
- •10.3.8.3Hiding
- •10.3.8.4This access
- •10.3.8.5Access to private and protected members of the containing type
- •10.3.8.6Nested types in generic classes
- •10.3.9Reserved member names
- •10.3.9.1Member names reserved for properties
- •10.5Fields
- •10.5.1Static and instance fields
- •10.5.2Readonly fields
- •10.5.2.1Using static readonly fields for constants
- •10.5.2.2Versioning of constants and static readonly fields
- •10.5.3Volatile fields
- •10.5.4Field initialization
- •10.5.5Variable initializers
- •10.5.5.1Static field initialization
- •10.5.5.2Instance field initialization
- •10.6Methods
- •10.6.1Method parameters
- •10.6.1.1Value parameters
- •10.6.1.2Reference parameters
- •10.6.1.3Output parameters
- •10.6.1.4Parameter arrays
- •10.6.2Static and instance methods
- •10.6.3Virtual methods
- •10.6.4Override methods
- •10.6.5Sealed methods
- •10.6.6Abstract methods
- •10.6.7External methods
- •10.6.8Partial methods
- •10.6.9Extension methods
- •10.6.10Method body
- •10.6.11Method overloading
- •10.7Properties
- •10.7.1Static and instance properties
- •10.7.2Accessors
- •10.7.3Automatically implemented properties
- •10.7.4Accessibility
- •10.7.5Virtual, sealed, override, and abstract accessors
- •10.8Events
- •10.8.1Field-like events
- •10.8.2Event accessors
- •10.8.3Static and instance events
- •10.8.4Virtual, sealed, override, and abstract accessors
- •10.9Indexers
- •10.9.1Indexer overloading
- •10.10Operators
- •10.10.1Unary operators
- •10.10.2Binary operators
- •10.10.3Conversion operators
- •10.11Instance constructors
- •10.11.1Constructor initializers
- •10.11.2Instance variable initializers
- •10.11.3Constructor execution
- •10.11.4Default constructors
- •10.11.5Private constructors
- •10.11.6Optional instance constructor parameters
- •10.12Static constructors
- •10.13Destructors
- •10.14Iterators
- •10.14.4.1The MoveNext method
- •10.14.4.2The Current property
- •10.14.4.3The Dispose method
- •10.14.5Enumerable objects
- •10.14.5.1The GetEnumerator method
- •10.14.6Implementation example
- •11.Structs
- •11.1Struct declarations
- •11.1.1Struct modifiers
- •11.3Class and struct differences
- •11.3.1Value semantics
- •11.3.2Inheritance
- •11.3.3Assignment
- •11.3.4Default values
- •11.3.5Boxing and unboxing
- •11.3.6Meaning of this
- •11.3.7Field initializers
- •11.3.8Constructors
- •11.3.9Destructors
- •11.3.10Static constructors
- •11.4Struct examples
- •11.4.1Database integer type
- •11.4.2Database boolean type
- •12.Arrays
- •12.1Array types
- •12.1.1The System.Array type
- •12.1.2Arrays and the generic iList interface
- •12.2Array creation
- •12.3Array element access
- •12.4Array members
- •12.5Array covariance
- •12.6Array initializers
- •13.Interfaces
- •13.1Interface declarations
- •13.1.1Interface modifiers
- •13.1.2Partial modifier
- •13.1.3Variant type parameter lists
- •13.1.3.1Variance safety
- •13.1.3.2Variance conversion
- •13.1.4Base interfaces
- •13.1.5Interface body
- •13.2Interface members
- •13.2.1Interface methods
- •13.2.2Interface properties
- •13.2.3Interface events
- •13.2.4Interface indexers
- •13.2.5Interface member access
- •13.3Fully qualified interface member names
- •13.4Interface implementations
- •13.4.1Explicit interface member implementations
- •13.4.2Uniqueness of implemented interfaces
- •13.4.3Implementation of generic methods
- •13.4.4Interface mapping
- •13.4.5Interface implementation inheritance
- •13.4.6Interface re-implementation
- •13.4.7Abstract classes and interfaces
- •14.Enums
- •14.1Enum declarations
- •14.2Enum modifiers
- •14.3Enum members
- •14.4The System.Enum type
- •14.5Enum values and operations
- •15.Delegates
- •15.1Delegate declarations
- •15.2Delegate compatibility
- •15.3Delegate instantiation
- •15.4Delegate invocation
- •16.Exceptions
- •16.1Causes of exceptions
- •16.2The System.Exception class
- •16.3How exceptions are handled
- •16.4Common Exception Classes
- •17.Attributes
- •17.1Attribute classes
- •17.1.1Attribute usage
- •17.1.2Positional and named parameters
- •17.1.3Attribute parameter types
- •17.2Attribute specification
- •17.3Attribute instances
- •17.3.1Compilation of an attribute
- •17.3.2Run-time retrieval of an attribute instance
- •17.4Reserved attributes
- •17.4.1The AttributeUsage attribute
- •17.4.2The Conditional attribute
- •17.4.2.1Conditional methods
- •17.4.2.2Conditional attribute classes
- •17.4.3The Obsolete attribute
- •17.5Attributes for Interoperation
- •17.5.1Interoperation with com and Win32 components
- •17.5.2Interoperation with other .Net languages
- •17.5.2.1The IndexerName attribute
- •18.Unsafe code
- •18.1Unsafe contexts
- •18.2Pointer types
- •18.3Fixed and moveable variables
- •18.4Pointer conversions
- •18.4.1Pointer arrays
- •18.5Pointers in expressions
- •18.5.1Pointer indirection
- •18.5.2Pointer member access
- •18.5.3Pointer element access
- •18.5.4The address-of operator
- •18.5.5Pointer increment and decrement
- •18.5.6Pointer arithmetic
- •18.5.7Pointer comparison
- •18.5.8The sizeof operator
- •18.6The fixed statement
- •18.7Fixed size buffers
- •18.7.1Fixed size buffer declarations
- •18.7.2Fixed size buffers in expressions
- •18.7.3Definite assignment checking
- •18.8Stack allocation
- •18.9Dynamic memory allocation
- •Documentation comments
- •Introduction
- •Recommended tags
- •Processing the documentation file
- •Id string format
- •Id string examples
- •An example
- •C# source code
- •Resulting xml
- •Keywords
- •Literals
- •Operators and punctuators
- •Syntactic grammar
- •Basic concepts
- •Variables
- •Expressions
- •Statements
- •Namespaces
- •Classes
- •Structs
- •Interfaces
- •Delegates
- •Attributes
- •Grammar extensions for unsafe code
- •References
- •Copyright ó Microsoft Corporation 1999-20101998. All Rights Reserved. Please send corrections, comments, and other feedback to csharp@microsoft.Com
7. Expressions 137
7.1 Expression classifications 137
7.1.1 Values of expressions 138
7.2 Static and Dynamic Binding 138
7.2.1 Binding-time 139
7.2.2 Dynamic binding 139
7.2.3 Types of constituent expressions 139
7.3 Operators 140
7.3.1 Operator precedence and associativity 140
7.3.2 Operator overloading 141
7.3.3 Unary operator overload resolution 142
7.3.4 Binary operator overload resolution 143
7.3.5 Candidate user-defined operators 143
7.3.6 Numeric promotions 143
7.3.6.1 Unary numeric promotions 144
7.3.6.2 Binary numeric promotions 144
7.3.7 Lifted operators 145
7.4 Member lookup 145
7.4.1 Base types 147
7.5 Function members 147
7.5.1 Argument lists 149
7.5.1.1 Corresponding parameters 150
7.5.1.2 Run-time evaluation of argument lists 151
7.5.2 Type inference 153
7.5.2.1 The first phase 154
7.5.2.2 The second phase 154
7.5.2.3 Input types 154
7.5.2.4 Output types 154
7.5.2.5 Dependence 154
7.5.2.6 Output type inferences 154
7.5.2.7 Explicit parameter type inferences 155
7.5.2.8 Exact inferences 155
7.5.2.9 Lower-bound inferences 155
7.5.2.10 Upper-bound inferences 156
7.5.2.11 Fixing 156
7.5.2.12 Inferred return type 156
7.5.2.13 Type inference for conversion of method groups 158
7.5.2.14 Finding the best common type of a set of expressions 158
7.5.3 Overload resolution 158
7.5.3.1 Applicable function member 159
7.5.3.2 Better function member 159
7.5.3.3 Better conversion from expression 160
7.5.3.4 Better conversion from type 161
7.5.3.5 Better conversion target 161
7.5.3.6 Overloading in generic classes 161
7.5.4 Compile-time checking of dynamic overload resolution 162
7.5.5 Function member invocation 162
7.5.5.1 Invocations on boxed instances 163
7.6 Primary expressions 163
7.6.1 Literals 164
7.6.2 Simple names 164
7.6.2.1 Invariant meaning in blocks 165
7.6.3 Parenthesized expressions 166
7.6.4 Member access 167
7.6.4.1 Identical simple names and type names 168
7.6.4.2 Grammar ambiguities 169
7.6.5 Invocation expressions 170
7.6.5.1 Method invocations 170
7.6.5.2 Extension method invocations 171
7.6.5.3 Delegate invocations 174
7.6.6 Element access 174
7.6.6.1 Array access 175
7.6.6.2 Indexer access 175
7.6.7 This access 176
7.6.8 Base access 177
7.6.9 Postfix increment and decrement operators 177
7.6.10 The new operator 178
7.6.10.1 Object creation expressions 178
7.6.10.2 Object initializers 180
7.6.10.3 Collection initializers 182
7.6.10.4 Array creation expressions 183
7.6.10.5 Delegate creation expressions 185
7.6.10.6 Anonymous object creation expressions 186
7.6.11 The typeof operator 188
7.6.12 The checked and unchecked operators 190
7.6.13 Default value expressions 192
7.6.14 Anonymous method expressions 192
7.7 Unary operators 192
7.7.1 Unary plus operator 193
7.7.2 Unary minus operator 193
7.7.3 Logical negation operator 193
7.7.4 Bitwise complement operator 194
7.7.5 Prefix increment and decrement operators 194
7.7.6 Cast expressions 195
7.8 Arithmetic operators 195
7.8.1 Multiplication operator 196
7.8.2 Division operator 197
7.8.3 Remainder operator 198
7.8.4 Addition operator 199
7.8.5 Subtraction operator 200
7.9 Shift operators 202
7.10 Relational and type-testing operators 203
7.10.1 Integer comparison operators 204
7.10.2 Floating-point comparison operators 205
7.10.3 Decimal comparison operators 206
7.10.4 Boolean equality operators 206
7.10.5 Enumeration comparison operators 206
7.10.6 Reference type equality operators 206
7.10.7 String equality operators 208
7.10.8 Delegate equality operators 208
7.10.9 Equality operators and null 209
7.10.10 The is operator 209
7.10.11 The as operator 209
7.11 Logical operators 210
7.11.1 Integer logical operators 211
7.11.2 Enumeration logical operators 211
7.11.3 Boolean logical operators 211
7.11.4 Nullable boolean logical operators 212
7.12 Conditional logical operators 212
7.12.1 Boolean conditional logical operators 213
7.12.2 User-defined conditional logical operators 213
7.13 The null coalescing operator 214
7.14 Conditional operator 214
7.15 Anonymous function expressions 215
7.15.1 Anonymous function signatures 217
7.15.2 Anonymous function bodies 217
7.15.3 Overload resolution 218
7.15.4 Anonymous functions and dynamic binding 219
7.15.5 Outer variables 219
7.15.5.1 Captured outer variables 219
7.15.5.2 Instantiation of local variables 220
7.15.6 Evaluation of anonymous function expressions 222
7.16 Query expressions 222
7.16.1 Ambiguities in query expressions 223
7.16.2 Query expression translation 223
7.16.2.1 Select and groupby clauses with continuations 224
7.16.2.2 Explicit range variable types 224
7.16.2.3 Degenerate query expressions 225
7.16.2.4 From, let, where, join and orderby clauses 225
7.16.2.5 Select clauses 229
7.16.2.6 Groupby clauses 229
7.16.2.7 Transparent identifiers 230
7.16.3 The query expression pattern 231
7.17 Assignment operators 232
7.17.1 Simple assignment 233
7.17.2 Compound assignment 235
7.17.3 Event assignment 236
7.18 Expression 236
7.19 Constant expressions 237
7.20 Boolean expressions 238