This section describes the process that takes place at run-time to invoke a particular function member. It is assumed that a compile-time process has already determined the particular member to invoke, possibly by applying overload resolution to a set of candidate function members.
For purposes of describing the invocation process, function members are divided into two categories:
this
(§7.5.7).The run-time processing of a function member invocation consists of the following steps, where M
is the function member and, if M
is an instance member, E
is the instance expression:
M
is a static function member:
M
is invoked.M
is an instance function member declared in a value-type:
E
is evaluated. If this evaluation causes an exception, then no further steps are executed.E
is not classified as a variable, then a temporary local variable of E
’s type is created and the value of E
is assigned to that variable. E
is then reclassified as a reference to that temporary local variable. The temporary variable is accessible as this
within M
, but not in any other way. Thus, only when E
is a true variable is it possible for the caller to observe the changes that M
makes to this
.M
is invoked. The variable referenced by E
becomes the variable referenced by this
.M
is an instance function member declared in a reference-type:
E
is evaluated. If this evaluation causes an exception, then no further steps are executed.E
is a value-type, a boxing conversion (§4.3.1) is performed to convert E
to type object
, and E
is considered to be of type object
in the following steps.E
is checked to be valid. If the value of E
is null
, a NullReferenceException
is thrown and no further steps are executed.M
is a non-virtual function member, then M
is the function member implementation to invoke. Otherwise, M
is a virtual function member and the function member implementation to invoke is determined through virtual function member lookup (§7.4.4) or interface function member lookup (§7.4.5).E
becomes the object referenced by this
.