What is a method?
You already know a little about functions, which are blocks of code with a name, that you can reuse. That block of code is a set of instructions you want a program to perform.
But what are methods?
Methods are also functions defined inside a class. Since everything in C# is defined inside a class, every function is also a method. You can, however, isolate instance methods that are executed within the context of an object from class methods, which operate directly on the class.
That sounds a bit abstract, so let’s break it down.
Defining instance methods
When you define a class, you define its fields in the form of variables. Then you can write methods to work with those fields.
For example, let's define a class with two integer numbers:
class MagicMath
{
int a;
int b;
}
Then you can create a method within the class that will change those values:
class MagicMath
{
int a;
int b;
public void ChangeValues()
{
a = 2;
b = 7;
}
}
Since this method is working with the values of fields that only exist once an object is created, it's called an instance method.
To be able to use an object of this class, you need to instantiate it by creating a variable of this class:
MagicMath magicMath = new MagicMath();
After that, you can call your new method to change values of the new instance of the class:
magicMath.ChangeValues();
As you noticed above, to call a method, you use a dot notation which is common in many programming languages. It means you need to write the name of an instance variable followed by the method name, separated by a dot: instanceVariableName.MethodName();
.
Back to our example, let's bring all the code together:
using System;
namespace Methods
{
public class Program
{
public static void Main()
{
MagicMath magicMath = new MagicMath();
Console.WriteLine("a=" + magicMath.a + ", b=" + magicMath.b);
magicMath.ChangeValues();
Console.WriteLine("a=" + magicMath.a + ", b=" + magicMath.b);
}
class MagicMath
{
public int a;
public int b;
public void ChangeValues()
{
this.a = 2;
this.b = 7;
}
}
}
}
Let's run this code:
a=0, b=0 a=2, b=7
Notice how we were able to print the content of the attributes before assigning a value? Contrary to what happens with local variables, C# initializes fields automatically with the default value for the type of the field if no value is provided.
If you want the object created with a different value than the default for each field, you need to write a constructor method. This method is called automatically when the object is instantiated and can set the values for the fields directly or through another method.
In C#, the constructor must have the same name as the class. It doesn’t have any return type; not even void
.
Here is an example with a constructor that uses a method to set the initial values:
public class MagicMath {
public int a;
public int b;
// Creates the object through the ChangeValues() method
public MagicMath()
{
this.ChangeValues();
}
// Sets a value of 1 for a and a value of 5 to b
public void ChangeValues()
{
this.a = 1;
this.b = 5;
}
}
Any object instantiated from this class will be initialized with the values defined in the ChangeValues
method.
Defining static members
As you know, you can create methods that use instance members of a class. You can also use static methods, which you can apply to the class in general and don't require the instantiation of an object. They work with static class members or perform some instructions that relate to the class in general.
In C#, static members (fields and methods) are marked with the static keyword at the declaration. Here is an example of a class method and a static field inside a class definition:
class ClassName
{
double instanceVariable;
static int classVariable;
public void InstanceMethod()
{
// can access both the instanceVariable and the classVariable
}
public static void ClassMethod()
{
// only works at the class level, can only access classVariable
}
}
To call class methods, you use the same dot notation as for instance methods. However, the call is made directly on the class name.
ClassName.ClassMethod();
For example, you can declare a class Car
with a static
field that will be incremented each time you create an instance of the class. That way, you will keep track of the number of Car
objects that have been created.
class Car
{
private static int count = 0;
public static void Increment()
{
Car.count += 1;
}
}
Every time you produce a Car
object, you can increase the count:
Car.Increment();
It's important to know the difference between the two categories of methods and make the appropriate decision for the implementation of your classes.
Let's reiterate:
Instance methods work in the context of an instance of a class. They require object instantiation.
Static methods operate in the context of a class in general, and do not require object instantiation.
Static methods are used inside static classes. They provide functionalities that can be used by several classes. The math class is one example.
On the other hand, blueprint classes are the most valuable because they define both a state (with fields) and a behavior (with instance methods). You have already seen that you can make sure an instance is created with the proper values thanks to a constructor. Let's now see how we can make sure the values remain relevant for your needs.
Control field values with properties
When working with classes and objects, you must make sure the object remains valid for its purpose from the time of creation until it is no longer used.
For this, two special class members are used:
Constructors - which ensure that proper values are given to the fields of the object as soon as it is created.
Properties - whose purpose is to control access to fields.
To define a property, you must define at minimum a getter or a setter, but you can define both.
Property getter - whose purpose is to return the current value of a field. This means that you can mark your fields as private, and only provide accessors for the ones that should be accessed by other classes.
Property setter - which not only control which fields can be modified, but can also enforce business rules on which values can be set.
For example, let's declare a Square
class with two fields: length and width. Here's what it looks like in C#:
public class Square
{
private int length;
private int width;
public Square(int length, int width)
{
this.length = length;
this.width = width;
}
public int Length
{
get
{
return this.length;
}
set
{
this.length = value;
}
}
}
And then we can use it:
public static void Main(String[] args)
{
// Create a square with a length of 10 and a width of 4
Square square = new Square(10, 4);
Console.WriteLine(square.length); // does not work: length is private
Console.WriteLine(square.Length); // -> 10
square.Length = 16;
Console.WriteLine(square.Length); // -> 16
}
If you are interested in an additional property that you can infer from existing fields (such as the perimeter), you can define one that will use of the fields.
Try it out for yourself!
Ready to get started? To access the exercise, click this link.
Let's recap!
In this chapter, you've learned:
Methods of a class are functions that operate in the context of that class.
Instance methods operate on fields of an instance of that class. Instance methods call on an object after it's been instantiated.
Static methods operate in the global context of a class and don't require instantiation of an object.
To call methods, a dot notation is commonly used:
instanceVariableName.MethodName
orClassName.MethodName
.Constructors and properties are special members that ensure the validity of the values of an object's fields.