Common Type System—Methods
Methods
Functions have existed in languages for quite some time, becoming the first way in which to abstract and reuse blocks of code whose execution differs based on input. A method is simply the object-oriented lingo for a function. Every piece of executable user code in the CTS is a method, be it a traditional-style method, a constructor, or a property getter/setter. In this section, we’ll look at what methods consist of, and also how they are called from other methods.
A method accepts any number of formal parameters (referred to as just parameters from here on), which are
essentially named variables that your method’s body has access to and that are supplied by callers
through actual arguments (referred to as just arguments). Methods also have a single output return parameter,
which is optional and can be typed as void to indicate one isn’t supplied. It is used to supply the caller
with information once the method completes. When we talk about parameters, the default is an input
parameter. The CTS also supports parameters passed by reference, which permits the caller and callee to
share the same references to the same data. We will see how to take advantage of these features in just a
few paragraphs.
The following code illustrates a method SomeMethod, which takes two parameters and returns a value:
class Calculator { public int Add(int x, int y) { return x + y; } }
This method might be called from user code, for example as follows:
Calculator calc = new Calculator(); int sum = calc.Add(3, 5);
The IL generated contains a call to the object referred to by sum’s Add method. The values 3 and 5 are
passed as the arguments for parameters x and y, respectively, for a single activation frame of the method
Add. The method then uses the dynamic values 3 and 5 from the frame, adding them together and
returning the result. The frame is then popped off, resulting in the number 8 being passed back to the
receiver; in this case, it stores it in its own local variable sum.
Methods, like any other member, can be instance or static. Instance methods have access to a special this
pointer when they execute (named this in C#, Me in VB)—referring to the instance on which the
method was called—using which they may access the public, protected, and private instance members
of the enclosing type (and public or protected members in its type’s hierarchy). For example, consider a
class with instance state:
class Example { int state; public void Foo() { state++; this.state++; } }
Note that C# infers the this qualification for the reference to the state field because it notices that an
instance variable is in scope. C# also supports explicit qualification with the this keyword. In either
case, the underlying IL encodes this access by loading the 0th argument of the activation frame. This is
the convention for passing the this pointer from a caller to a receiving instance method. All other real
arguments begin at 1.
Static methods, conversely, have no this pointer. They have access to private static members of the
enclosing type, but there is no active instance passed on which to access instance members. Arguments
for static methods begin at 0. This is entirely transparent if you stay inside the world of C#. But at the IL
level you must recognize and deal with the difference.
|

