Now that we have discussed the type system, primitive types, operators, methods, and basic statements and loops, we can start to learn about the defining characteristic of C# and object-oriented programming in general: classes.

A group of young men and women sit in a lecture hall; their faces are not visible.
Properties of this class include isBoring, isTooLong, amHungry, and isItOverYet. Photo by Sam Balye / Unsplash

The Sample Project

exceptionnotfound/CSharpInSimpleTerms
Contribute to exceptionnotfound/CSharpInSimpleTerms development by creating an account on GitHub.
Project for this post: 7Classes

Classes

A class in C# is a definition that can be used to create instances of that class. Classes are created using the class keyword. C# classes are always reference types.

class TestClass 
{
    //An empty C# class
}

By convention, C# classes use Pascal Naming; each word in the class name should have their first letter capitalized.

Members

Classes can have members. Members are any objects in a class that are part of the class definition; everything defined in a class is a member of that class. This includes:

  • Fields - Members of the class that hold values and must be accessed directly. Each of these will have a type.
  • Properties - Members of the class which provides a way to read, write, or change a value held by a field.
  • Methods - A code block containing a set of statements that will be executed. Methods may or may not return a value of a given type.
  • Constructors - A special kind of method which sets the initial values for the properties in the class.

Class Instances

We create an instance of a class using the new keyword:

var myInstance = new TestClass();

We can then manipulate the instance by changing its property values, invoking methods or constructors, etc.

Class Fields

When writing a C# class, we define fields in the class by giving them a type.

class ExampleClass
{
    string Property1; //Default null
    int Property2; //Default 0
    decimal Property3; //Default 0.0
}

When an instance of a class is created, each of the class's fields will get their default value.

var myClass = new ExampleClass();
Console.WriteLine(myClass.Property1); //Null
Console.WriteLine(myClass.Property2); //0
Console.WriteLine(myClass.Property3); //0.0

Access Modifiers

Each field or property in a C# class can be declared with a access modifier, which is a keyword that specifies who or what can access that field or property.

  • Private - Property is only accessible inside of instances of this class.
  • Protected - Property is accessible by instances of this class AND instances of classes which inherit from this class.
  • Public - Property is accessible from any code in any assembly which references the assembly for this class.
  • Internal - Property is accessible from any code in the same assembly only.

By default, all properties declared without an access modifier are private. We can set the access modifier on properties like so:

class ExampleClass
{
    public string Property1;
    protected int Property2;
    private decimal Property3;
}

Getter and Setter Methods

Fields are direct members of the class and must be accessed directly. This is a bad idea in most cases; generally we want to use properties rather than fields.

Properties provide a way to modify and access a value in the class. They are backed by a field, which holds said value, and use access modifiers.

For public or protected properties we can declare getter and setter methods, which often use the syntax { get; set; }:

class ExampleClass
{
    public string Property1 { get; set; }
    protected int Property2 { get; set; }
    private decimal Property3;
}

To be clear: a property has getter and/or setter methods, and a field has neither.

If we want to allow other classes or objects to access a private field (such as Property3 in the example above), we can declare a public property and modify its getter and setter methods to read and change the field's value:

class ExampleClass
{
    public string Property1 { get; set; }
    protected int Property2 { get; set; }
    private decimal Property3;
    
    public decimal PublicProperty3 
    {
        get
        {
            return Property3;
        }
        set
        {
            Property3 = value;
        }
    }
}

In this case, the property PublicProperty3 stores and retrieves values from the field Property3.

Auto-Implemented Properties

In most cases, if we want the property to be modifiable outside of the class it is declared in, declaring a public property with getter and setter methods is the way to go. Behind the scenes, doing this actually creates a private field and get/set methods for the property. Plus, it makes our code much cleaner:

class ExampleClass
{
    public string Property1 { get; set; }
    protected int Property2 { get; set; }
    public decimal Property3 { get; set; }
}

Properties written this way are called auto-implemented properties. The vast majority of the time, when you are writing a program in C#, your classes will use auto-implemented properties.

Calculated Properties

We can also make calculated properties which use the values of other properties in the same class to return a value of their own. Calculated properties will only have a getter method:

class ExampleClass
{
    public string ItemName { get; set; }
    protected int Quantity { get; set; }
    public decimal ItemPrice { get; set; }
    
    public decimal TotalCost
    {
        get
        {
            return Quantity * ItemPrice;
        }
    }
}

Class Access Modifiers

Just like class properties, C# classes themselves can use access modifiers.

public class PublicClass { /*...*/ }
protected class ProtectedClass { /*...*/ }
private class PrivateClass { /*...*/ }
class InternalClass { /*...*/ } //Default access modifier is internal

Classes which are declared directly within a namespace my be either public or internal; internal is the default. Namespaces will be discussed in Part 11 of this series.

In general, a derived class (that is, a class which inherits from another class) cannot have greater accessibility than its parent. We cannot, for example, do this:

internal class ClassA { /*...*/ }
public class ClassB : ClassA { /*...*/ }
Error: Inconsistent accessibility: base class ClassA is less accessible than class ClassB

However, a public class can inherit from a private class. The derived class must at least as accessible as the parent class.

Methods

A C# class can have methods. Just like properties, methods have access modifiers, and their default access modifier is private.

public class ClassC
{
    public string Property1 { get; set; }
    
    public void Method1() { /*...*/ }
    
    public string MethodWithReturn() 
    { 
        /*...*/ 
        return "stringValue";
    }
}

Methods in a class may also have input parameters:

public class ClassD
{
    public string MethodWithParameters(int param1, string param2, decimal param3) 
    { 
        /*...*/ 
        return "stringValue";
    }
}

Methods in classes are subject to the same rules as methods in general; refer to the previous post in this series for more information.

Constructors

A C# class will always have at least one method which is a constructor; this method is responsible for assigning the default values for the properties of the class when an instance of it is created. The constructor method must have the same name as the class and no return type.

public class ClassE
{
    public ClassE() { /* Constructor Method */ }
}

We can specify input parameters to a constructor, just like any other method. Further, our classes can have multiple constructors, as long as each constructor has a different set of input parameters.

public class ClassF
{
    public string Property1 { get; set; }
    public int Property2 { get; set; }

    public ClassF(int param1)
    {
        Property2 = param1;
    }

    public ClassF(string param1)
    {
        Property1 = param1;
    }

    public ClassF(string param1, int param2)
    {
        Property1 = param1;
        Property2 = param2;
    }
}

var myClassF = new ClassF("stringValue");
var otherClassF = new ClassF("stringValue", 6);

Implicit Constructors

If we do not specify a constructor method, the C# compiler will create an implicit constructor, which will be invoked whenever we create a new instance of a class and don't pass any parameters to the constructor. This kind of constructor is also called a public parameterless constructor, because it will be public and have no parameters.

public class ClassG
{
    public string Property1 { get; set; }
    public int Property2 { get; set; }
}

var myClassG = new ClassG();

Of course, we can also create a public parameterless constructor:

public class ClassH
{
    public string Property1 { get; set; }
    public int Property2 { get; set; }
    
    public ClassH() { /* Public parameterless constructor */ }
}

var myClassH = new ClassH();

Glossary

  • Instance - a single object created from a class or object definition.
  • Member - a property, method, constructor, or other object that is part of a class.
  • Property - a specific value member of a class. Has getter and setter methods.
  • Getter and setter methods - Specialized methods which retrieve (get) and change (set) the value of a particular property.
  • Auto-implemented properties - Properties which use the { get; set; } syntax and do not specify custom getter and setter methods.
  • Calculated properties - Properties which return values based on the current value of other properties in the same class.
  • Access modifier - keywords which determine the level of access to give a class.
  • Fields - direct-access properties in a class. Generally, we want to avoid using these in favor of using properties with getters and setters.
  • Constructor - a specialized method that sets the initial values of properties in a class.
  • Implicit constructor - A constructor generated automatically by the compiler. Classes without a defined constructor will have an implicit constructor.

New Keywords

  • class - Used to define a C# class.
  • get and set - Used to define getter and setter methods respectively for class properties.
  • new - Creates a new instance of an object.

Summary

Classes in C# are collections of properties, methods, constructors, and other members; instances of a class are created using these definitions and the new keyword. Instances of classes are always reference types.

C# classes support many kinds of properties, including auto-implemented properties, calculated properties, and private properties. Properties have get and set methods which allow us to retrieve and modify the value of the property; properties which do not have getter or setter methods are termed fields, and directly modifying field values is often (though not always) bad practice.

Access modifiers (e.g. public, private, protected, etc.) allow programmers to specify the level of access for properties, methods, and the classes themselves.

Methods in C# classes behave the same as methods elsewhere; they can be invoked on instances of the class.

All C# classes must have at least one constructor. This is a special method that sets the initial values for a class's properties and fields when an instance of the class is created. Constructors do not specify a return type, not even void. We can define our own constructors, provided that each has a different set of input parameters. If no constructors are defined, C#'s compiler will ensure that the class automatically has a public parameterless constructor.

Still have questions? I can help! Ask them in the comments below!

In the next part of our series, we dive into two special value types in C#, and discuss what they are used for. Check out the Structs and Enums part of the C# in Simple Terms mega series!

C# in Simple Terms - Structs and Enums
Two useful value types team up! Let’s see how structs and enums work.

Happy Coding!