News & UpdatesProgrammingWeb programming StoreMy Projects
Links
Affiliates

C# Tutorial – 10 – Methods

Methods are reusable code blocks that will only execute when called.

Defining methods

A method can be created inside a class by typing void followed by the method’s name, a set of parentheses and a code block. The void keyword means that the method will not return a value. The naming convention for methods is the same as for classes – a descriptive name with each word initially capitalized.

class MyApp
{
  void MyPrint()
  {
    System.Console.Write("Hello World");
  }
}

All methods in C# must belong to a class, and they are the only place where statements may be executed. C# does not have global functions, which are methods defined outside of classes.

Calling methods

The method above will print out a text message. To invoke (call) it an instance of the MyApp class must first be created by using the new keyword. The dot operator is then used after the instance’s name to access its members, which includes the MyPrint method.

class MyApp
{
  static void Main()
  {
    MyApp m = new MyApp();
    m.MyPrint(); // "Hello World"
  }
 
  void MyPrint()
  {
    System.Console.Write("Hello World");
  }
}

Method parameters

The parentheses that follow the method name are used to pass arguments to the method. To do this the corresponding parameters must first be specified in the method definition in the form of a comma separated list of variable declarations.

void MyPrint(string s1, string s2)
{
  System.Console.Write(s1 + s2);
}

A method can be defined to take any number of arguments, and they can have any data types. Just ensure the method is called with the same types and number of arguments.

static void Main()
{
  MyApp m = new MyApp();
  m.MyPrint("Hello", " World"); // "Hello World"
}

To be precise, parameters appear in method definitions, while arguments appear in method calls. However, the two terms are sometimes used interchangeably.

Params keyword

To take a variable number of arguments of a specific type, an array with the params modifier can be added as the last parameter in the list. Any extra parameters of the specified type that are passed to the method will automatically be stored in that array.

void MyPrint(params string[] s)
{
  foreach (string x in s)
    System.Console.Write(x);
}

Method overloading

It is possible to declare multiple methods with the same name as long as the parameters vary in type or number. This is called method overloading and can for example be seen in the implementation of the System.Console.Write method, which has 18 method definitions. It is a powerful feature that allows a method to handle a variety of arguments without the programmer needing to be aware of using different methods.

void MyPrint(string s)
{
  System.Console.Write(s);
}
 
void MyPrint(int i)
{
  System.Console.Write(i);
}

Optional parameters

As of C# 4.0, parameters can be declared as optional by providing a default value for them in the method declaration. When the method is invoked, these optional arguments may be omitted to use the default values.

class MyApp
{
  void MySum(int i, int j = 0, int k = 0)
  {
    System.Console.Write(1*i + 2*j + 3*k);
  }
 
  static void Main()
  {
    new MyApp().MySum(1, 2); // "5"
  }
}

Named arguments

C# 4.0 also introduced named arguments, which allow an argument to be passed using the name of its corresponding parameter. This feature complements optional parameters by enabling arguments to be passed out of order, instead of relying on their position in the parameter list. Therefore, any optional parameters can be specified without having to specify the value for every optional parameter before it. Both optional and required parameters can be named, but the named arguments must be placed after the unnamed ones.

static void Main()
{
  new MyApp().MySum(1, k: 2); // "7"
}

Return statement

A method can return a value. The void keyword is then replaced with the data type that the method will return, and the return keyword is added to the method body with an argument of the specified return type.

string GetPrint()
{
  return "Hello";
}

Return is a jump statement that causes the method to exit and return the value to the place where the method was called. For example, the GetPrint method above can be passed as an argument to the Write method since the method evaluates to a string.

static void Main()
{
  MyApp m = new MyApp();
  System.Console.Write( m.GetPrint() ); // "Hello World"
}

The return statement may also be used in void methods to exit before the end block is reached.

void MyMethod()
{
  return;
}

Value and reference types

There are two kinds of data types in C#: value types and reference types. Variables of value types directly contain their data, whereas variables of reference types hold references to their data. The reference types in C# include: class, interface, array and delegate types. The value types include the simple types, as well as the struct, enum and nullable types. Reference type variables are typically created using the new keyword, though that is not always necessary, as for example in the case of string objects.

A variable of a reference type is generally called an object, though strictly speaking the object is the data that the variable refers to. With reference types, multiple variables can reference the same object, and therefore operations performed through one variable will affect any other variables that reference the same object. In contrast, with value types, each variable will store its own value and operations on one will not affect another.

Passing value types

When passing parameters of value type only a local copy of the variable is passed, so if the copy is changed it will not affect the original variable.

void Set(int i) { i = 10; }
 
static void Main()
{
  MyApp m = new MyApp();
  int x = 0; // value type
  m.Set(x);  // pass value of x
  System.Console.Write(x); // "0"
}

Passing reference types

For reference data types the object reference will be passed by value. This means that it is possible to change the state (fields) of the original object. However, if the object is replaced with a new instance only the local object reference will be changed.

void Set(int[] i) { i[0] = 10; }
 
static void Main()
{
  MyApp m = new MyApp();
  int[] y = { 0 }; // reference type
  m.Set(y);        // pass object reference
  System.Console.Write(y[0]); // "10"
}

Ref keyword

A variable of value or reference type can be passed by reference by using the ref keyword, both in the caller and method declaration. This will cause the variable to be passed in by reference, and therefore changing it will update the original value.

void Set(ref int i) { i = 10; }
 
static void Main()
{
  MyApp m = new MyApp();
  int x = 0;    // value type
  m.Set(ref x); // pass reference to value type
  System.Console.Write(x); // "10"
}

Out keyword

Sometimes you may want to pass an unassigned variable by reference and have it assigned in the method. However, using an unassigned local variable will give a compile-time error. For this situation the out keyword can be used. It has the same function as ref, except that the compiler will allow use of the unassigned variable, and it will force you to actually set the variable in the method.

void Set(out int i) { i = 10; }
 
static void Main()
{
  MyApp m = new MyApp();
  int x;        // value type
  m.Set(out x); // pass reference to unset value type
  System.Console.Write(x); // "10"
}