C# Classes & Objects Tutorial

In this tutorial we learn how to model our application after entities in the real world with classes.

We cover how to define a class, instantiate an instance object, class attributes and methods, class constructors and destructors, static members and how to refer to the calling object with this.

Here's a table of contents of what you'll learn in this lesson:
(click on a link to skip to its section)

Let's jump right in.

What is a class

A class is like a blueprint to model our application after entities in the real world. A class is similar to a struct , but with more power and flexibility.

How to define a class

To define a class we use the keyword class , followed by a name and a code block.

Unlike a struct, a class body is not terminated with a semicolon.

Syntax:
class Indentifier
{
    // class body
}
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args){}
    }
}

Throughout the tutorial series we’ve been working inside a class called Program.

Class attributes and methods

A class can have members such as variables and functions. We declare and use these members inside a class, we’ve been doing it inside the Main function so far.

Syntax:
class Identifier
{
    varType varIdentifier;

    funcType FuncIdentifier()
    {
        // function body
    }
}
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args){}
    }

    class Car
    {
        float topSpeed;

        void Move()
        {

        }
    }
}

In the example above we create a class called Car, with a variable and function.

How to instantiate a class object

A class object is an instance of the class. Think of it this way, if a class is the blueprint for a car, then an object is the car itself.

An object must be instantiated with the new keyword, which creates a new instance of the class.

Syntax:
classIdentifier objectIdentifier = new classIdentifier();
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car();
        }
    }

    class Car
    {
        float topSpeed;

        void Move()
        {

        }
    }
}

In the example above, we instantiated a new object of the Car class. We can now work with the members of the class.

How to set default values with a class constructor

When an object is instantiated, we can establish defaults for its members.

A class comes with a default constructor that sets all field data of the class to an appropriate default value.

We can redefine this default constructor with our own default values. A constructor looks like a function and has the same name as the class.

Syntax:
class Identifier
{
    varType varName;

    Identifier()
    {
        varName = defaultValue;
    }
}
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car();

            Console.WriteLine(myCar.topSpeed);
            Console.ReadLine();
        }
    }

    class Car
    {
        public float topSpeed;

        public Car()
        {
            topSpeed = 300f;
        }
    }
}

In the example above, we set the value of the topSpeed variable inside the constructor. All Car objects will start their lives with topSpeed set to 300.

We use the dot operator to access class members.

How to set up a custom class constructor

We can set up our own custom constructors with extra parameters. Then, when the object is instantiated, we can specify which of those constructors we want to use based on the parameters we input.

Syntax:
class Identifier
{
    varType varName;

    Identifier(parameterList)
    {
        varName = parameter;
    }
}
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car(4);

            Console.WriteLine("My car has " + myCar.seating + " seats");
            Console.ReadLine();
        }
    }

    class Car
    {
        public int seating;
        public float topSpeed;

        public Car()
        {
            topSpeed = 300f;
        }

        public Car(int seats)
        {
            seating = seats;
        }
    }
}

In the example above, when we instantiated the object we entered a number as a parameter.

The compiler picked up that the number is an int, saw that there’s a constructor that takes an int as a parameter and used that constructor instead of the default one.

How to refer to the calling object with this

The this keyword is used to reference the calling object, i.e specify the current class.

Syntax:
 this.identifier

We use the dot operator between this and the identifier.

Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car(4);

            Console.WriteLine("My car has " + myCar.seating + " seats");
            Console.ReadLine();
        }
    }

    class Car
    {
        public int seating;
        public float topSpeed;

        public Car()
        {
            topSpeed = 300f;
        }

        public Car(int seating)
        {
            this.seating = seating;
        }
    }
}

In the example above we explicitly tell the compiler that this.seating belongs to the class and not the function.

How to set up a class destructor

A destructor is useful for releasing memory resources before exiting the application.

Destructors can’t be inherited or overloaded.

Syntax:
class Identifier
{
    varType varName;

    ~Identifier()
    {
        // destructor body
    }
}
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car();
        }
    }

    class Car
    {
        public Car()
        {
            Console.WriteLine("Object constructed");
        }

        ~Car()
        {
            Console.WriteLine("Object deconstructed");
        }
    }
}

In the example above we instantiate a new object and call its default constructor. Just before the application exits, the deconstructor will be called.

How to declare static class members

When we declare a class member as static , it implies that only one instance of the member exists for a class. Static data is allocated once and shared among all objects of the same class.

A static member must be invoked directly from the class level, rather than from the object reference variable.

As a demonstration, let’s look at the Console.WriteLine() class function, as it is a static member.

We do not invoke the WriteLine() method from the object level:

Example:
Console c = new Console();
c.WriteLine("Compiler error, I am not an object level function!");

Instead, we prefix the class name to the static WriteLine() function with the dot operator:

Example:
Console.WriteLine("I'm invoked directly from the class level");
How to define static field data

To define a static member we use the static keyword in front of the type.

Syntax:
// Property
static type identifier;

// Function
static funcType funcIdentifier()
{
    // function body
}
Example:
using System;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Statics.message);
            Statics.Message();

            Console.ReadLine();
        }
    }

    class Statics
    {
        public static string message = "Static field";

        public static void Message()
        {
            Console.WriteLine("Static function, no need for object instances");
        }
    }
}

In the example above we make use of the static members of the class without instantiating an object.

Static data is allocated to memory once and shared among all instances of the class. As a result you save a little memory space.

How to declare a static class

In C# it’s possible to define an entire class as static. When we define a class as static, we can’t create it with the new keyword.

A static class can only contain members that are static, otherwise the compiler will raise an error.

Syntax:
static class Identifier
{
    static varIdentifier;

    static funcIdentifier(parameterList)
    {
        // function body
    }
}
Example:
using System;
using DateTime;

namespace Classes
{
    class Program
    {
        static void Main(string[] args)
        {
            Statics.CurrentTime();
            Statics.CurrentTimeSeconds();

            Console.ReadLine();
        }
    }

    static class Statics
    {
        public static void CurrentTime()
        {
            Console.WriteLine("Current time: {0}", DateTime.Now.ToShortTimeString());
        }

        public static void CurrentTimeSeconds()
        {
            Console.WriteLine("Current time: {0}", DateTime.Now.ToLongTimeString());
        }
    }
}

In the example above, we create a static class with two static functions. When we use them in the Main() function, we don’t instantiate new objects, we directly call class.function().

Summary: Points to remember

  • A class acts as a blueprint for an object. A class allows us to model our application after entities in the real world.
  • Classes live on the heap, whereas structs live on the stack.
  • Variables and functions inside classes are called attributes and methods respectively. Or, class members as a whole.
  • When instantiating an object with the new keyword, we create an instance of the class. If the class is a pizza recipe, the instance object is the pizza itself.
  • We can set default values when instantiating an object if we create a class constructor.
    • A class constructor is a function with the same name as the class itself.
  • We are allowed to have multiple constructors with parameters. The compiler will automatically identify the one we want to use from the object instantiation.
  • Inside a class, we refer to the class itself (the calling object) with the keyword this. For example, this.variable_name refers to variable_name inside the class.
  • A class destructor will release memory used by the class when we’re done using it. If a destructor is available, it will automatically be called.
  • Static class members will keep their values throughout the application lifetime.
    • The keyword static is used in front of the member name to identify it as static.
    • Static members are called by class and member name with dot notation. For example, Console.WriteLine().
  • Entire classes can be static, in which case they aren’t instantiated into objects.
    • When a class is static, all of its members must be static too.