
- •Foreword
- •Introduction
- •Scope
- •Conformance
- •Normative references
- •Definitions
- •Notational conventions
- •Acronyms and abbreviations
- •General description
- •Language overview
- •Getting started
- •Types
- •Predefined types
- •Conversions
- •Array types
- •Type system unification
- •Variables and parameters
- •Automatic memory management
- •Expressions
- •Statements
- •Classes
- •Constants
- •Fields
- •Methods
- •Properties
- •Events
- •Operators
- •Indexers
- •Instance constructors
- •Destructors
- •Static constructors
- •Inheritance
- •Static classes
- •Partial type declarations
- •Structs
- •Interfaces
- •Delegates
- •Enums
- •Namespaces and assemblies
- •Versioning
- •Extern Aliases
- •Attributes
- •Generics
- •Why generics?
- •Creating and consuming generics
- •Multiple type parameters
- •Constraints
- •Generic methods
- •Anonymous methods
- •Iterators
- •Lexical structure
- •Programs
- •Grammars
- •Lexical grammar
- •Syntactic grammar
- •Grammar ambiguities
- •Lexical analysis
- •Line terminators
- •Comments
- •White space
- •Tokens
- •Unicode escape sequences
- •Identifiers
- •Keywords
- •Literals
- •Boolean literals
- •Integer literals
- •Real literals
- •Character literals
- •String literals
- •The null literal
- •Operators and punctuators
- •Pre-processing directives
- •Conditional compilation symbols
- •Pre-processing expressions
- •Declaration directives
- •Conditional compilation directives
- •Diagnostic directives
- •Region control
- •Line directives
- •Pragma directives
- •Basic concepts
- •Application startup
- •Application termination
- •Declarations
- •Members
- •Namespace members
- •Struct members
- •Enumeration members
- •Class members
- •Interface members
- •Array members
- •Delegate members
- •Member access
- •Declared accessibility
- •Accessibility domains
- •Protected access for instance members
- •Accessibility constraints
- •Signatures and overloading
- •Scopes
- •Name hiding
- •Hiding through nesting
- •Hiding through inheritance
- •Namespace and type names
- •Unqualified name
- •Fully qualified names
- •Automatic memory management
- •Execution order
- •Types
- •Value types
- •The System.ValueType type
- •Default constructors
- •Struct types
- •Simple types
- •Integral types
- •Floating point types
- •The decimal type
- •The bool type
- •Enumeration types
- •Reference types
- •Class types
- •The object type
- •The string type
- •Interface types
- •Array types
- •Delegate types
- •Boxing and unboxing
- •Boxing conversions
- •Unboxing conversions
- •Variables
- •Variable categories
- •Static variables
- •Instance variables
- •Instance variables in classes
- •Instance variables in structs
- •Array elements
- •Value parameters
- •Reference parameters
- •Output parameters
- •Local variables
- •Default values
- •Definite assignment
- •Initially assigned variables
- •Initially unassigned variables
- •Precise rules for determining definite assignment
- •General rules for statements
- •Block statements, checked, and unchecked statements
- •Expression statements
- •Declaration statements
- •If statements
- •Switch statements
- •While statements
- •Do statements
- •For statements
- •Break, continue, and goto statements
- •Throw statements
- •Return statements
- •Try-catch statements
- •Try-finally statements
- •Try-catch-finally statements
- •Foreach statements
- •Using statements
- •Lock statements
- •General rules for simple expressions
- •General rules for expressions with embedded expressions
- •Invocation expressions and object creation expressions
- •Simple assignment expressions
- •&& expressions
- •|| expressions
- •! expressions
- •?: expressions
- •Anonymous method expressions
- •Yield statements
- •Variable references
- •Atomicity of variable references
- •Conversions
- •Implicit conversions
- •Identity conversion
- •Implicit numeric conversions
- •Implicit enumeration conversions
- •Implicit reference conversions
- •Boxing conversions
- •Implicit type parameter conversions
- •Implicit constant expression conversions
- •User-defined implicit conversions
- •Explicit conversions
- •Explicit numeric conversions
- •Explicit enumeration conversions
- •Explicit reference conversions
- •Unboxing conversions
- •User-defined explicit conversions
- •Standard conversions
- •Standard implicit conversions
- •Standard explicit conversions
- •User-defined conversions
- •Permitted user-defined conversions
- •Evaluation of user-defined conversions
- •User-defined implicit conversions
- •User-defined explicit conversions
- •Anonymous method conversions
- •Method group conversions
- •Expressions
- •Expression classifications
- •Values of expressions
- •Operators
- •Operator precedence and associativity
- •Operator overloading
- •Unary operator overload resolution
- •Binary operator overload resolution
- •Candidate user-defined operators
- •Numeric promotions
- •Unary numeric promotions
- •Binary numeric promotions
- •Member lookup
- •Base types
- •Function members
- •Argument lists
- •Overload resolution
- •Applicable function member
- •Better function member
- •Better conversion
- •Function member invocation
- •Invocations on boxed instances
- •Primary expressions
- •Literals
- •Simple names
- •Invariant meaning in blocks
- •Parenthesized expressions
- •Member access
- •Identical simple names and type names
- •Invocation expressions
- •Method invocations
- •Delegate invocations
- •Element access
- •Array access
- •Indexer access
- •This access
- •Base access
- •Postfix increment and decrement operators
- •The new operator
- •Object creation expressions
- •Array creation expressions
- •Delegate creation expressions
- •The typeof operator
- •The checked and unchecked operators
- •Default value expression
- •Anonymous methods
- •Anonymous method signatures
- •Anonymous method blocks
- •Outer variables
- •Captured outer variables
- •Instantiation of local variables
- •Anonymous method evaluation
- •Implementation example
- •Unary expressions
- •Unary plus operator
- •Unary minus operator
- •Logical negation operator
- •Bitwise complement operator
- •Prefix increment and decrement operators
- •Cast expressions
- •Arithmetic operators
- •Multiplication operator
- •Division operator
- •Remainder operator
- •Addition operator
- •Subtraction operator
- •Shift operators
- •Relational and type-testing operators
- •Integer comparison operators
- •Floating-point comparison operators
- •Decimal comparison operators
- •Boolean equality operators
- •Enumeration comparison operators
- •Reference type equality operators
- •String equality operators
- •Delegate equality operators
- •The is operator
- •The as operator
- •Logical operators
- •Integer logical operators
- •Enumeration logical operators
- •Boolean logical operators
- •Conditional logical operators
- •Boolean conditional logical operators
- •User-defined conditional logical operators
- •Conditional operator
- •Assignment operators
- •Simple assignment
- •Compound assignment
- •Event assignment
- •Expression
- •Constant expressions
- •Boolean expressions
- •Statements
- •End points and reachability
- •Blocks
- •Statement lists
- •The empty statement
- •Labeled statements
- •Declaration statements
- •Local variable declarations
- •Local constant declarations
- •Expression statements
- •Selection statements
- •The if statement
- •The switch statement
- •Iteration statements
- •The while statement
- •The do statement
- •The for statement
- •The foreach statement
- •Jump statements
- •The break statement
- •The continue statement
- •The goto statement
- •The return statement
- •The throw statement
- •The try statement
- •The checked and unchecked statements
- •The lock statement
- •The using statement
- •The yield statement
- •Namespaces
- •Compilation units
- •Namespace declarations
- •Extern alias directives
- •Using directives
- •Using alias directives
- •Using namespace directives
- •Namespace members
- •Type declarations
- •Qualified alias member
- •Classes
- •Class declarations
- •Class modifiers
- •Abstract classes
- •Sealed classes
- •Static classes
- •Class base specification
- •Base classes
- •Interface implementations
- •Class body
- •Partial declarations
- •Class members
- •Inheritance
- •The new modifier
- •Access modifiers
- •Constituent types
- •Static and instance members
- •Nested types
- •Fully qualified name
- •Declared accessibility
- •Hiding
- •this access
- •Reserved member names
- •Member names reserved for properties
- •Member names reserved for events
- •Member names reserved for indexers
- •Member names reserved for destructors
- •Constants
- •Fields
- •Static and instance fields
- •Readonly fields
- •Using static readonly fields for constants
- •Versioning of constants and static readonly fields
- •Volatile fields
- •Field initialization
- •Variable initializers
- •Static field initialization
- •Instance field initialization
- •Methods
- •Method parameters
- •Value parameters
- •Reference parameters
- •Output parameters
- •Parameter arrays
- •Static and instance methods
- •Virtual methods
- •Override methods
- •Sealed methods
- •Abstract methods
- •External methods
- •Method body
- •Method overloading
- •Properties
- •Static and instance properties
- •Accessors
- •Virtual, sealed, override, and abstract accessors
- •Events
- •Field-like events
- •Event accessors
- •Static and instance events
- •Virtual, sealed, override, and abstract accessors
- •Indexers
- •Indexer overloading
- •Operators
- •Unary operators
- •Binary operators
- •Conversion operators
- •Instance constructors
- •Constructor initializers
- •Instance variable initializers
- •Constructor execution
- •Default constructors
- •Private constructors
- •Optional instance constructor parameters
- •Static constructors
- •Destructors
- •Structs
- •Struct declarations
- •Struct modifiers
- •Struct interfaces
- •Struct body
- •Struct members
- •Class and struct differences
- •Value semantics
- •Inheritance
- •Assignment
- •Default values
- •Boxing and unboxing
- •Meaning of this
- •Field initializers
- •Constructors
- •Destructors
- •Static constructors
- •Struct examples
- •Database integer type
- •Database boolean type
- •Arrays
- •Array types
- •The System.Array type
- •Array creation
- •Array element access
- •Array members
- •Array covariance
- •Arrays and the generic IList interface
- •Array initializers
- •Interfaces
- •Interface declarations
- •Interface modifiers
- •Base interfaces
- •Interface body
- •Interface members
- •Interface methods
- •Interface properties
- •Interface events
- •Interface indexers
- •Interface member access
- •Fully qualified interface member names
- •Interface implementations
- •Explicit interface member implementations
- •Interface mapping
- •Interface implementation inheritance
- •Interface re-implementation
- •Abstract classes and interfaces
- •Enums
- •Enum declarations
- •Enum modifiers
- •Enum members
- •The System.Enum type
- •Enum values and operations
- •Delegates
- •Delegate declarations
- •Delegate instantiation
- •Delegate invocation
- •Exceptions
- •Causes of exceptions
- •The System.Exception class
- •How exceptions are handled
- •Common Exception Classes
- •Attributes
- •Attribute classes
- •Attribute usage
- •Positional and named parameters
- •Attribute parameter types
- •Attribute specification
- •Attribute instances
- •Compilation of an attribute
- •Run-time retrieval of an attribute instance
- •Reserved attributes
- •The AttributeUsage attribute
- •The Conditional attribute
- •Conditional Methods
- •Conditional Attribute Classes
- •The Obsolete attribute
- •Unsafe code
- •Unsafe contexts
- •Pointer types
- •Fixed and moveable variables
- •Pointer conversions
- •Pointers in expressions
- •Pointer indirection
- •Pointer member access
- •Pointer element access
- •The address-of operator
- •Pointer increment and decrement
- •Pointer arithmetic
- •Pointer comparison
- •The sizeof operator
- •The fixed statement
- •Stack allocation
- •Dynamic memory allocation
- •Generics
- •Generic class declarations
- •Type parameters
- •The instance type
- •Members of generic classes
- •Static fields in generic classes
- •Static constructors in generic classes
- •Accessing protected members
- •Overloading in generic classes
- •Parameter array methods and type parameters
- •Overriding and generic classes
- •Operators in generic classes
- •Nested types in generic classes
- •Generic struct declarations
- •Generic interface declarations
- •Uniqueness of implemented interfaces
- •Explicit interface member implementations
- •Generic delegate declarations
- •Constructed types
- •Type arguments
- •Open and closed types
- •Base classes and interfaces of a constructed type
- •Members of a constructed type
- •Accessibility of a constructed type
- •Conversions
- •Using alias directives
- •Generic methods
- •Generic method signatures
- •Virtual generic methods
- •Calling generic methods
- •Inference of type arguments
- •Using a generic method with a delegate
- •Constraints
- •Satisfying constraints
- •Member lookup on type parameters
- •Type parameters and boxing
- •Conversions involving type parameters
- •Iterators
- •Iterator blocks
- •Enumerator interfaces
- •Enumerable interfaces
- •Yield type
- •This access
- •Enumerator objects
- •The MoveNext method
- •The Current property
- •The Dispose method
- •Enumerable objects
- •The GetEnumerator method
- •Implementation example
- •Lexical grammar
- •Line terminators
- •White space
- •Comments
- •Unicode character escape sequences
- •Identifiers
- •Keywords
- •Literals
- •Operators and punctuators
- •Pre-processing directives
- •Syntactic grammar
- •Basic concepts
- •Types
- •Expressions
- •Statements
- •Classes
- •Structs
- •Arrays
- •Interfaces
- •Enums
- •Delegates
- •Attributes
- •Generics
- •Grammar extensions for unsafe code
- •Undefined behavior
- •Implementation-defined behavior
- •Unspecified behavior
- •Other Issues
- •Capitalization styles
- •Pascal casing
- •Camel casing
- •All uppercase
- •Capitalization summary
- •Word choice
- •Namespaces
- •Classes
- •Interfaces
- •Enums
- •Static fields
- •Parameters
- •Methods
- •Properties
- •Events
- •Case sensitivity
- •Avoiding type name confusion
- •Documentation Comments
- •Introduction
- •Recommended tags
- •<code>
- •<example>
- •<exception>
- •<list>
- •<para>
- •<param>
- •<paramref>
- •<permission>
- •<remarks>
- •<returns>
- •<seealso>
- •<summary>
- •<value>
- •Processing the documentation file
- •ID string format
- •ID string examples
- •An example
- •C# source code
- •Resulting XML
Chapter 14 Expressions
114.5.10 The new operator
2The new operator is used to create new instances of types.
3There are three forms of new expressions:
4• Object creation expressions are used to create new instances of class types and value types.
5• Array creation expressions are used to create new instances of array types.
6• Delegate creation expressions are used to create new instances of delegate types.
7The new operator implies creation of an instance of a type, but does not necessarily imply dynamic
8allocation of memory. In particular, instances of value types require no additional memory beyond the
9variables in which they reside, and no dynamic allocations occur when new is used to create instances of
10value types.
1114.5.10.1 Object creation expressions
12An object-creation-expression is used to create a new instance of a class-type or a value-type.
13object-creation-expression:
14 |
new type ( argument-listopt ) |
15The type of an object-creation-expression shall be a class-type, a value-type, or a type-parameter having the
16constructor-constraint or the value type constraint (§26.7). The type cannot be an abstract class-type.
17The optional argument-list (§14.4.1) is permitted only if the type is a class-type or a struct-type, and not a
18type-parameter.
19The compile-time processing of an object-creation-expression of the form new T(A), where T is a class-
20type, a value-type, or a type-parameter, and A is an optional argument-list, consists of the following steps:
21• If T is a value-type and A is not present:
22o The object-creation-expression is a default constructor invocation. The result of the object-creation-
23expression is a value of type T, namely the default value for T as defined in §11.1.1.
24• Otherwise, if T is a class-type or a struct-type:
25o If T is an abstract class-type, a compile-time error occurs.
26o The instance constructor to invoke is determined using the overload resolution rules of §14.4.2. The
27set of candidate instance constructors consists of all accessible instance constructors declared in T. If
28the set of candidate instance constructors is empty, or if a single best instance constructor cannot be
29identified, a compile-time error occurs.
30o The result of the object-creation-expression is a value of type T, namely the value produced by
31invoking the instance constructor determined in the step above.
32• Otherwise, if T is a type-parameter:
33o If A is present, a compile-time error occurs.
34o Otherwise, if T has the constructor-constraint or the value type constraint, the result of the object-
35creation-expression is a value of type T.
36o Otherwise, the object-creation-expression is invalid, and a compile-time error occurs.
37• Otherwise, the object-creation-expression is invalid, and a compile-time error occurs.
38The run-time processing of an object-creation-expression of the form new T(A), where T is class-type, a
39struct-type, or a type-parameter, and A is an optional argument-list, consists of the following steps:
40• If T is a class-type:
41o A new instance of class T is allocated. If there is not enough memory available to allocate the new
42instance, a System.OutOfMemoryException is thrown and no further steps are executed.
171
C# LANGUAGE SPECIFICATION
1o All fields of the new instance are initialized to their default values (§12.2).
2o The instance constructor is invoked according to the rules of function member invocation (§14.4.3).
3A reference to the newly allocated instance is automatically passed to the instance constructor and
4the instance can be accessed from within that constructor as this.
5• If T is a struct-type:
6o An instance of type T is created by allocating a temporary local variable. Since an instance
7constructor of a struct-type is required to definitely assign a value to each field of the instance being
8created, no initialization of the temporary variable is necessary.
9o The instance constructor is invoked according to the rules of function member invocation (§14.4.3).
10A reference to the newly allocated instance is automatically passed to the instance constructor and
11the instance can be accessed from within that constructor as this.
12• If T is a type-parameter:
13o If T evaluates at run-time to a value type, the result is the default value of this type (§11.1.2). This is
14always the case if T has the value type constraint.
15o Otherwise T shall evaluate at run-time to a non-abstract class type having a public constructor taking
16no parameters. The result is a new instance of this class type:
17• A new instance of the class is allocated. If there is not enough memory available to allocate the
18 |
new instance, a System.OutOfMemoryException is thrown and no further steps are |
19 |
executed. |
20• All fields of the new instance are initialized to their default values (§12.2).
21• The instance constructor is invoked according to the rules of function member invocation
22 |
(§14.4.3). A reference to the newly allocated instance is automatically passed to the instance |
23 |
constructor and the instance can be accessed from within that constructor as this. |
24[Note: The run-time type need not be accessible to the code containing the object-creation-
25expression. Nevertheless, the run-time environment shall support invoking the constructor. end note]
26
2714.5.10.2 Array creation expressions
28An array-creation-expression is used to create a new instance of an array-type.
29array-creation-expression:
30 |
new non-array-type [ expression-list ] rank-specifiersopt array-initializeropt |
31new array-type array-initializer
32An array creation expression of the first form allocates an array instance of the type that results from
33deleting each of the individual expressions from the expression list. [Example: The array creation expression
34new int[10,20] produces an array instance of type int[,], and the array creation expression new
35int[10][,] produces an array of type int[][,]. end example] Each expression in the expression list
36shall be of type int, uint, long, or ulong, or of a type that can be implicitly converted to one or more of
37these types. The value of each expression determines the length of the corresponding dimension in the newly
38allocated array instance. Since the length of an array dimension shall be nonnegative, it is a compile-time
39error to have a constant expression with a negative value, in the expression list.
40Except in an unsafe context (§25.1), the layout of arrays is unspecified.
41If an array creation expression of the first form includes an array initializer, each expression in the
42expression list shall be a constant expression (§14.15) and the rank and dimension lengths specified by the
43expression list shall match those of the array initializer.
172
Chapter 14 Expressions
1In an array creation expression of the second form, the rank of the specified array type shall match that of
2the array initializer. The individual dimension lengths are inferred from the number of elements in each of
3the corresponding nesting levels of the array initializer. Thus, the expression
4new int[,] {{0, 1}, {2, 3}, {4, 5}}
5exactly corresponds to
6new int[3, 2] {{0, 1}, {2, 3}, {4, 5}}
7Array initializers are described further in §19.7.
8The result of evaluating an array creation expression is classified as a value, namely a reference to the newly
9allocated array instance. The run-time processing of an array creation expression consists of the following
10steps:
11• The dimension length expressions of the expression-list are evaluated in order, from left to right.
12Following evaluation of each expression, an implicit conversion (§13.1) to one of the following types is
13performed: int, uint, long, ulong. The first type in this list for which an implicit conversion exists is
14chosen. If evaluation of an expression or the subsequent implicit conversion causes an exception, then
15no further expressions are evaluated and no further steps are executed.
16• The computed values for the dimension lengths are validated, as follows: If one or more of the values
17are less than zero, a System.OverflowException is thrown and no further steps are executed.
18• An array instance with the given dimension lengths is allocated. If there is not enough memory available
19to allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are
20executed.
21• All elements of the new array instance are initialized to their default values (§12.2).
22• If the array creation expression contains an array initializer, then each expression in the array initializer
23is evaluated and assigned to its corresponding array element. The evaluations and assignments are
24performed in the order the expressions are written in the array initializer—in other words, elements are
25initialized in increasing index order, with the rightmost dimension increasing first. If evaluation of a
26given expression or the subsequent assignment to the corresponding array element causes an exception,
27then no further elements are initialized (and the remaining elements will thus have their default values).
28An array creation expression permits instantiation of an array with elements of an array type, but the
29elements of such an array shall be manually initialized. [Example: The statement
30int[][] a = new int[100][];
31creates a single-dimensional array with 100 elements of type int[]. The initial value of each element is
32null. It is not possible for the same array creation expression to also instantiate the sub-arrays (without an
33array initializer), and the statement
34 |
int[][] a = new int[100][5]; |
// Error |
35results in a compile-time error. Instantiation of the sub-arrays can instead be performed manually or using an
36array initializer, as in
37int[][] a = new int[100][];
38for (int i = 0; i < 100; i++) a[i] = new int[5];
39int[][] b = new int[3][] { new int[1], new int[2], new int[3] };
40end example]
41[Note:When an array of arrays has a “rectangular” shape, that is when the sub-arrays are all of the same
42length, it is more efficient to use a multi-dimensional array. In the example above, instantiation of the array
43of arrays creates 101 objects—one outer array and 100 sub-arrays. In contrast,
44int[,] = new int[100, 5];
45creates only a single object, a two-dimensional array, and accomplishes the allocation in a single statement.
46end note]
173
C# LANGUAGE SPECIFICATION
114.5.10.3 Delegate creation expressions
2A delegate-creation-expression is used to create a new instance of a delegate-type.
3delegate-creation-expression:
4 |
new delegate-type ( expression ) |
5The argument of a delegate creation expression shall be a method group (§14.1), an anonymous-method-
6expression (§14.5.14), or a value of a delegate-type. If the argument is a method group, it identifies the
7method, type arguments (for a generic method) and, for an instance method, the object for which to create a
8delegate. If the argument is a value of a delegate-type, it identifies a delegate instance of which to create a
9copy.
10If the expression is an anonymous-method-expression (§14.5.14), then the anonymous method is converted
11to the given delegate type using the implicit conversion rules defined in §13.5. [Example: If D is a delegate
12type, then the expression
13new D(delegate { Console.WriteLine("hello"); })
14is equivalent to the expression
15(D) delegate { Console.WriteLine("hello"); }
16end example]
17The compile-time processing of a delegate-creation-expression of the form new D(E), where D is a
18delegate-type and E is an expression, consists of the following steps:
19• If E is a method group:
20o A single method is selected corresponding to a method invocation (§14.5.5.1) of the form E(A),
21with the following modifications:
22• The parameter types and modifiers (ref or out) of D are used as the argument types and
23 |
modifiers of the argument list A. |
24 |
• The candidate methods considered are only those methods that are applicable in their normal |
25 |
form (§14.4.2.1), not those applicable only in their expanded form. |
26 |
• If the algorithm of §14.5.5.1 produces an error, then a compile-time error occurs. Otherwise the |
27 |
algorithm produces a single best method M, together with its type arguments (if the method is |
28 |
generic), having the same number of parameters as D. |
29o If the selected M is not consistent (§22.1) with the delegate type D, a compiler-time error occurs.
30o If the method M is an instance method, the instance expression associated with E determines the
31target object of the delegate.
32o The result is a value of type D, namely a newly created delegate that refers to the method M and
33target object.
34• Otherwise, if E is a value of a delegate-type:
35o If D and E have different numbers of parameters, a compile-time error occurs.
36o If there is not an identity conversion or implicit reference conversion from the return type of E to the
37return type of D, a compile-time error occors.
38o If for some parameter of D there is not an identity conversion or implicit reference conversion from
39the parameter type to the corresponding parameter type of E, a compile-time error occurs.
40o If any parameter of D or E has a parameter modifier (ref or out), then the other corresponding
41parameter must have the same modifier and the same type.
42o The result is a value of type D, namely a newly created delegate that refers to the same invocation
43list as E.
44• Otherwise, the delegate creation expression is invalid, and a compile-time error occurs.
174
Chapter 14 Expressions
1The run-time processing of a delegate-creation-expression of the form new D(E), where D is a delegate-type
2and E is an expression, consists of the following steps:
3• If E is a method group:
4o If the method selected at compile-time is a static method, the target object of the delegate is null.
5Otherwise, the selected method is an instance method, and the target object of the delegate is
6determined from the instance expression associated with E:
7• The instance expression is evaluated. If this evaluation causes an exception, no further steps are
8 |
executed. |
9 |
• If the instance expression is of a reference-type, the value computed by the instance expression |
10 |
becomes the target object. If the target object is null, a System.NullReferenceException |
11 |
is thrown and no further steps are executed. |
12 |
• If the instance expression is of a value-type, a boxing operation (§11.3.1) is performed to |
13 |
convert the value to an object, and this object becomes the target object. |
14o A new instance of the delegate type D is allocated. If there is not enough memory available to
15allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are
16executed.
17o The new delegate instance is initialized with a reference to the method that was determined at
18compile-time and a reference to the target object computed above.
19• If E is a value of a delegate-type:
20o E is evaluated. If this evaluation causes an exception, no further steps are executed.
21o If the value of E is null, a System.NullReferenceException is thrown and no further steps
22are executed.
23o A new instance of the delegate type D is allocated. If there is not enough memory available to
24allocate the new instance, a System.OutOfMemoryException is thrown and no further steps are
25executed.
26o The new delegate instance is initialized with references to the same invocation list as the delegate
27instance given by E.
28The method and object to which a delegate refers are determined when the delegate is instantiated and then
29remain constant for the entire lifetime of the delegate. In other words, it is not possible to change the target
30method or object of a delegate once it has been created. [Note: Remember, when two delegates are
31combined or one is removed from another, a new delegate results; no existing delegate has its content
32changed. end note]
33It is not possible to create a delegate that refers to a property, indexer, user-defined operator, instance
34constructor, destructor, or static constructor.
35[Example: As described above, when a delegate is created from a method group, the formal parameter list
36and return type of the delegate determine which of the overloaded methods to select. In the example
37delegate double DoubleFunc(double x);
38class A
39{
40 |
DoubleFunc f = new DoubleFunc(Square); |
41 |
static float Square(float x) { |
42 |
return x * x; |
43 |
} |
44 |
static double Square(double x) { |
45 |
return x * x; |
46}
47}
175