Methods in C# are operations associated with types. To provide a type with methods is to give it some useful functionality. Often this functionality is made generally available so that it can be utilized by other types
To take a simple example, suppose that we have an
Arithmetic class, whose purpose is to provide arithmetic operations. One simple method this class could have is the
addTwoIntegers method, whose job is to support the operation of adding two integers. To make use of this functionality, a piece of code would call the method by passing it two integers. The method would then return their sum. Such a piece of code might look like this:
A method declaration, specified within a class declaration, comprises a method-head and a method-body. The method-head is made up of the following elements (square brackets enclose those which are optional).
In the case of the example method, its method head could look something like this:
Let’s discuss all the elements of a C# method one by one:
- C# Method Attributes
- C# Method Modifiers
- C# Method Parameters
- C# Method Return Type
- C# Method Overloading
C# Method Attributes
Method attributes work in a similar way to that briefly described for classes. They can be used to associate declarative information - you can retrieve such information at runtime at a later point of time if need be using reflection.
In other words, you can use attributes to inject additional information to the assemblies that can be queried at runtime if needed using reflection. An attribute comprises of its name and optionally, a list of parameters. The attribute name corresponds to the attribute class.
The Obsolete attribute can be used to denote a method as obsolete - one that shouldn’t be used anymore as it is no longer needed or may have some other alternative. The following code snippet illustrates how you can use the Obsolete attribute on top of a method declaration.
If you use this method in your code and compile your program, you would see a warning displayed in the output window of the Visual Studio IDE. You can ignore this warning if you want to. You can learn more about c# attributes here.
C# Method Modifiers
There are ten method modifiers that can be used. Four of these - public, internal, protected and private - are the access modifiers that can be used in class declarations (see C# Class Modifiers). These four work similar to the way they work in class declarations. The others are the following:
In an abstract class, it is possible to specify a class method without specifying its body. Such methods are themselves termed
abstract. Abstract methods are discussed in previous article.
static modifier declares a method to be a class method.
The methods (as well as the enumerations, properties, and variables) specified in a class can be associated either with the class’s instances (ie. the reference types it specifies) or with the class itself. These methods are called, respectively, ‘instance methods’ and ‘class methods’. Class methods, declared with the
static modifier, can be called even when there exist no current instances of the class.
There is no equivalent modifier for instance methods since methods are instance methods just in case their declaration does not include the word
new, virtual, override
These modifiers concern the inheritance of methods from super - to sub-classes. They are covered in the next article.
When a method declaration includes an extern modifier, that method is said to be an external method. External methods are implemented externally, typically using a language other than C#. Because an external method declaration provides no actual implementation, the method-body of an external method simply consists of a semicolon. You can learn more about c# extern modifier here.
C# Method Parameters
A method’s parameters are the types that get passed to it when the method is called. The list of parameters begins by specifying zero or more ‘fixed parameters’, or it may finish by specifying a single parameter-array. This latter element - is declared using the
params keyword - means that it is possible to pass an arbitrary number of types to a single method.
Fixed parameter specifications can have either two or three parts (ignoring attributes). The first, optional modifier can be either
out. The second part of the specification specifies the parameter’s type, and the third part its name. Examples of these different elements can be seen in the illustrative code in the sections below.
Passing By Value
The parameter modifiers
out relate to how the parameter is passed into the method. Where neither of these modifiers is used, the parameter is passed in ‘by value’. In this case, when the method is called the value given is copied to the variable specified in the method declaration. The following example illustrates this point; note that the change made to variable b in the body of the
change method doesn’t result in a change to the variable used to invoke the method.
In this example, it was a value type that was passed ‘by value’. But reference types can also be passed ‘by value’. As we saw previously, the immediate value held by a reference type variable is actually a memory address. So when this variable is passed ‘by value’, the memory address is copied to the variable specified in the method head. But of course, because the two variables will hold the same memory address, any changes made within the method body to the object located at that memory address will be reflected outside the method (although this doesn’t apply for immutable reference types like strings, which act more like value types - see lesson 4).
Passing By Reference
In C# we can pass variables into methods ‘by reference’. Where a variable is passed by reference, the
ref modifier must be used both in the method head and the method invocation (illustrated by the next code block).
Passing by reference is most obviously useful in cases where we want to treat a value type like a reference type. For instance, the method call in the following code does change the value of the variable a passed into the
Where a method parameter is defined (and invoked) using the
out modifier, it is passed by reference. The difference between the
out and the
ref modifier is this: a parameter modified by the
out keyword need not be assigned a value before being passed into the method, but must be assigned a value in the method.
The reason that one might use output parameters is to return multiple values from a method. For instance, in the following code, an integer and a boolean is passed to the
change method. This method sets the boolean to indicate whether or not the integer is greater than 0, and returns the value of the integer doubled.
The Params Modifier
One can pass an arbitrary number of types to a method by declaring a parameter array with the
params modifier. Note, though, that it is not necessary to place these additional types into an array before calling the method - they can simply be listed in the method invocation (see the next code block for an example).
Types passed as
params are all passed by value. The following code gives an example of the use of the
params modifier; the method called ignores the first type passed to it (a double) and returns the sum of all (an arbitrary number of) the integer values passed to it.
C# Method Return Type
Methods can either return a type or not. A method that doesn’t return a type must give its return type as
void. A method that does return a type must name the type returned.
A method will stop and return a value if it reaches a
return statement at any point in its execution. The type returned is given at the end of such a return statement; its type must correspond with that specified in the method declaration. The following piece of code illustrates this point.
C# Method Overloading
Each method has a signature. This comprises the method’s name and its parameters (excepting their names), but not the method’s return type. In the following method header, the elements making up the method’s signature are emphasized - note also that the
params keyword is not included in the signature.
The importance of the signature is that no class is allowed to contain two methods with the same signature. Since the signature takes in more than the method name, however, one class can have methods sharing a name. For example, a class with the method whose header is given above might also contain a method with the header:
Note, however, that since neither its return type nor the params keyword is part of a method’s signature this class could not also contain a method with the header:
Subscribe to Code with Shadman
Get the latest posts delivered right to your inbox