A method is a function that is a member of a class or struct.
The heading for a method looks like this:
access-modifier [static] return-type Name(argument list)
The access modifier may be any of the usual choices. The default (if not specified) is private.
A method may be static, in which case it is accessed by:
classname.methodname(...);
A static method cannot refer to "this", as it is not called from a specific instance. It can refer to static data members or other static methods, and it can use whatever it receives as arguments.
It is legal but somewhat questionable to have private static methods.
The variables in the argument list must have been assigned values before the method is called. (However, see the "out" modifier below.)
void
The type void is used in a method declaration to indicate that the method does not return any value. For example (in some class):
void OurFunction()
Here OurFunction does not return any value (and would not make sense in an assignment statement, for instance).
It would not be correct to use void in an argument list:
void OurFunction(void) // This is an error.
return
The return statement is used to terminate execution of a method and return control to the calling method. It may also provide a "return value" to the calling method.
If the method is declared as void, there is no return value and the return statement may optionally be omitted. (Execution ends at the end of the scope.)
If the method has a return type, there must be a return statement providing a value.
In exception handling, we may have a return statement in a "try" block. If there is a "finally" block, it will be executed before control returns to the calling method.
Parameter Passing
When a method is called, the default behavior is that parameters are passed by value. That is, the method will receive a copy of whatever is passed in. (This is the same default behavior as in the C language.)
The result of this is that the method may try to change the value it receives, and this change lasts during the call to the method, but the variable back in the calling code is unchanged.
Example:
In a class called MyClass1, I have
void MyMethod1(int A)
{
A = 3;
}
and in my main program, I have
MyClass1 WWW;
int J = 5;
...
WWW.MyMethod1(J);
Although MyMethod1 has tried to set J = 3, the variable J in the main program is unchanged.
End of Example
Here we used an integer, which is a value type. If we instead use a reference type, the situation is more interesting. The method receives a copy of the reference but not of the data to which the reference refers. (This is sometimes called a shallow copy.) (This is an example of having two references to the same data.) Thus the method is allowed to change the data but cannot permanently change the reference it started with.
Example:
In a class called MyClass2, I have
void MyMethod2(int [] A)
{
A[1] = 14;
A = new int[5] = { 0, -2, -4, -6, -8 };
}
and in my main program, I have
MyClass2 XXX;
int [] J = new int[3] = { 5, 7, 9 };
...
XXX.MyMethod2(J);
The result of this is that, back in the main program, J is still the same array of 3 integers, but J[1] has been changed to 14. The line creating a new array of 5 integers affects the local copy of the reference variable A, but the original reference variable J is not changed, still referring to an array of 3 integers.
End of Example
The ref modifier
Suppose we do want the method to be able to make actual changes in its parameter.
One way to do this is to use the "ref" modifier. This causes C# to skip the copying, and the method is working directly with its parameter.
Example:
In a class called MyClass3, I have
void MyMethod3(ref int A)
{
A = 14;
}
and in my main program, I have
MyClass3 YYY;
int J = -21;
...
YYY.MyMethod3(ref J);
The result is that in the main program, the value of J has been changed to 14.
End of Example
Notice that the modifier "ref" must be used both in the method heading and when the method is called.
The out modifier
A similar idea is the "out" modifier. Sometimes a parameter is intended to be used only for output. In that case, we can get around the need to assign it a value before using it as a parameter by using "out". It is then mandatory that the parameter must be assigned a value by the method.
Example:
In a class called MyClass4, I have
void MyMethod4(out int A)
{
A = 14;
}
and in my main program, I have
MyClass4 ZZZ;
int J; // Notice J has no initial value.
...
ZZZ.MyMethod4(out J);
J now has the value 14.
End of Example
Notice that the modifier "out" must be used both in the method heading and when the method is called.
The params modifier
Sometimes it is useful to be able to give a method a variable number of parameters. This can be done with the "params" modifier to indicate that we have a "parameter array".
A parameter array has to come at the end of the list of parameters, and it must be a 1-dimensional array. When the method is called, the parameter array (after any other parameters) may contain any number of items, all of the indicated type, or it may contain an ordinary array.
Example:
In a class called MyClass5, I have
void MyMethod5(char X, params int[] Numbers)
{
... // code using Numbers as an array
}
and in my main program, I have
MyClass5 PQR;
int [] H = new int[4] = { 9, 8, 7, 6 };
...
PQR.MyMethod5('Z', 4, 5, 6); // Numbers will be an array of 3 integers.
...
PQR.MyMethod5('R', H); // Numbers will be the array H.
End of Example
Of course, the parameter array could be of any type, not only int.