C# Methods, part 1 - Static Methods
(Page 4 of 6 )
In Object Oriented Programming, all methods must exist in the context of a class (or a structure), but sometimes you will find that there are methods that don't fit into an instance of the class, such as the Console.WriteLine() method. This method is not associated with an instance of a console, and it doesn't make any sense to instantiate an object of the Console class to call the WriteLine() method. At the same time, we don't want to write global functions because it violates the Object Oriented Design Principals.
The solution is to write static methods. A static method has a class scope, not an object scope, so it pertains to the class itself, not to an instance of the class. Actually, you can use static methods in two scenarios. The first scenario occurs when your class contains only functionality where it doesn't make any sense to instantiate an object of that class. So you can declare that your class is sealed, which means that it will not be instantiated, and create all your fields, properties and methods as static to provide the functionality without a violation to the OOP Design Principals. The second scenario is to use a static method in your usual classes to provide functionality that all the objects of that type need. We will modify the Employee class with a static method to understand how that can affect the class.
Another important issue about static methods is, which class members can the static methods access? Of course a static method has access to static fields, static properties and static constructors too. Static methods can't access an instance method; this makes sense because you might have three instance methods and one static method, so the instance methods can access the static method because it's only one known block of code that has a known memory address and behavior, so all instance methods see it. But the static method can't access non-static methods, because at runtime the behavior may do some damage to the object's state, and this is not allowed. Let's look at an example of a static method with our Employee class:
using System;
namespace MyCompany
{
public class Methods
{
static void Main(string[] args)
{
Employee Michael = new Employee("Michael", "Youssef", 7000m, Position.Engineer);
Console.WriteLine(Michael.MonthlySalary);
Michael.RaiseSalary();
// another Employee
Employee Steven = new Employee("Steven", "Peter", 9000m, Position.Manager);
Console.WriteLine(Steven.MonthlySalary);
Steven.RaiseSalary();
Console.WriteLine("--------------------------");
//call to the static method
Console.WriteLine("The company has " +Employee.GetEmpNumber()+ " employees");
Console.ReadLine();
}
}
public class Employee
{
public string FirstName;
public string LastName;
public decimal MonthlySalary;
public Position EmpPosition;
private static int EmpCounter;
public Employee(string FN, string LN, decimal MS, Position EP)
{
this.FirstName = FN;
this.LastName = LN;
this.MonthlySalary = MS;
this.EmpPosition = EP;
Employee.EmpCounter++;
}
public static int GetEmpNumber()
{
return Employee.EmpCounter;
}
public void RaiseSalary()
{
switch(this.EmpPosition)
{
case Position.Accountant:
Console.WriteLine("The employee salary will be raised 10%");
this.MonthlySalary = this.MonthlySalary * 1.10m;
Console.WriteLine("The employee salary now = " + this.MonthlySalary);
break;
case Position.Lawyer:
Console.WriteLine("The employee salary will be raised 15%");
this.MonthlySalary = this.MonthlySalary * 1.15m;
Console.WriteLine("The employee salary now = " + this.MonthlySalary);
break;
case Position.Engineer:
Console.WriteLine("The employee salary will be raised 20%");
this.MonthlySalary = this.MonthlySalary * 1.20m;
Console.WriteLine("The employee salary now = " + this.MonthlySalary);
break;
case Position.Manager:
Console.WriteLine("The employee salary will be raised 25%");
this.MonthlySalary = this.MonthlySalary * 1.25m;
Console.WriteLine("The employee salary now = " + this.MonthlySalary);
break;
}
}
}
public enum Position
{
Accountant = 1,
Lawyer,
Engineer,
Manager
}
}
The result is:

We have added a private static field (EmpCounter) and a static method (GetEmpNumber()) which returns the total number of our employees by returning the value of the EmpCounter static field. Note that we increase the EmpCounter field by 1 in the Employee's constructor, which proves that the instance method (in our case the Constructor) accesses the static field and increases it by 1. Note that we use the class name in order to access the static member, and within the static methods you can't use the this keyword, because this refers to the current instance, which is not the case with a static member.
A class such as the Console class is called a group abstraction, which means that it contains static members only, and it can't be instantiated. This is an important design issue, and you must follow this design; when you have a class that contains a lot of instance methods and static methods, try to separate the static methods into a group abstraction class, and put the instance method into another class. It's usual to have something like two or three static members in your class, but if you have 20, it's better to follow the group abstraction design and make that class sealed.
Next: Methods and StackFrame >>
More C# Articles
More By Michael Youssef