
- •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.6.10.6Anonymous object creation expressions
An anonymous-object-creation-expression is used to create an object of an anonymous type.
anonymous-object-creation-expression: new anonymous-object-initializer
anonymous-object-initializer: { member-declarator-listopt } { member-declarator-list , }
member-declarator-list: member-declarator member-declarator-list , member-declarator
member-declarator: simple-name member-access base-access identifier = expression
An anonymous object initializer declares an anonymous type and returns an instance of that type. An anonymous type is a nameless class type that inherits directly from object. The members of an anonymous type are a sequence of read-only properties inferred from the anonymous object initializer used to create an instance of the type. Specifically, an anonymous object initializer of the form
new { p1 = e1 , p2 = e2 , … pn = en }
declares an anonymous type of the form
class __Anonymous1 { private readonly T1 f1 ; private readonly T2 f2 ; … private readonly Tn fn ;
public __Anonymous1(T1 a1, T2 a2,…, Tn an) { f1 = a1 ; f2 = a2 ; … fn = an ; }
public T1 p1 { get { return f1 ; } } public T2 p2 { get { return f2 ; } } … public Tn pn { get { return fn ; } }
public override bool Equals(object o) { … } public override int GetHashCode() { … } }
where each Tx is the type of the corresponding expression ex. The expression used in a member-declarator must have a type. Thus, it is a compile-time error for an expression in a member-declarator to be null or an anonymous function. It is also a compile-time error for the expression to have an unsafe type.
The name of an anonymous type is automatically generated by the compiler and cannot be referenced in program text.
Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type.
In the example
var p1 = new { Name = "Lawnmower", Price = 495.00 }; var p2 = new { Name = "Shovel", Price = 26.95 }; p1 = p2;
the assignment on the last line is permitted because p1 and p2 are of the same anonymous type.
The Equals and GetHashcode methods on anonymous types override the methods inherited from object, and are defined in terms of the Equals and GetHashcode of the properties, so that two instances of the same anonymous type are equal if and only if all their properties are equal.
A member declarator can be abbreviated to a simple name (§7.5.2), a member access (§7.5.4) or a base access (§7.6.8). This is called a projection initializer and is shorthand for a declaration of and assignment to a property with the same name. Specifically, member declarators of the forms
identifier expr . identifier
are precisely equivalent to the following, respectively:
identifer = identifier identifier = expr . identifier
Thus, in a projection initializer the identifier selects both the value and the field or property to which the value is assigned. Intuitively, a projection initializer projects not just a value, but also the name of the value.