(C# Language) class, record and struct

We expect you have a very general understanding of object oriented programming blocks like classes and structs. In this tutorial we have a quick look at a class in C#. Then we have a discussion of the structs, and then a detailed look on the record keyword. The tutorial closes with "When to use a record".
(Rev. 18-Jun-2024)

Categories | About |     |  

Parveen,

Table of Contents (top down ↓)

class in C#

A class in C# is about the same as in other object oriented languages. Data members can be marked public, private and protected. Data members are also called fields in C#.

A constructor can be used to initialize data members. A constructor that accepts no parameters is called a default constructor, whereas a constructor that accepts parameters is called a parameterized constructor.

Public functions or methods can be executed on the objects of a class.


// except for small difference in syntax, 
// a class is about the same as in other 
// object oriented languages 

class MyClass
{
  private int I;

  public MyClass(int i)
  {
    I = i;
  }

  public void Print()
  {
    Console.WriteLine(I);
  }
}

An object can be created with the new keyword MyClass obj = new MyClass(5);


// top level statements 
// or the Main function 

MyClass obj = new MyClass(5);

obj.Print();

The new expression can be simplified in newer versions of C#. We could have done it this way also MyClass obj = new (5);


// simplified syntax for creating an object 

MyClass obj = new (5);

obj.Print();

Video Explanation (see it happen!)

Please watch the following youtube video:

struct in C#

A struct in C# is recommended for holding values - the rule of thumb is to use a struct if the data members are numeric types. For example, there is a built-in struct called Point that stores the co-ordinates of a point. Another built-in struct is DateTime - which stores the number of ticks.

A struct can contain a constructor. It doesn't participate in inheritance.

structs are copied as value when passing as arguments to functions and methods.

records in C#

A record is mainly used for creating init-once type of data.

The following single line syntax public record class MyData (String name, int ID); defines an init-once record to hold a string and an int type of data. Compiler generates the proper constructor and data members for holding the data.


// notice the simpler syntax of defining a 
// record. the compiler generates everything  
// for us. 

public record class MyData (String name, int ID);

Object of this record can be created by using the usual syntax MyData obj = new ("Aus", 1);

The data can be printed by using console writeline. The compiler provides the ToString method for records. The output is in a readable format MyData { Name = Aus, ID = 1 }.

Since this record is not mutable, any attempt to modify a property fails with a compiler error.


MyData obj = new ("Aus", 1);

// ToString is provided by the compiler 
// for printing in good format 
// Prints- MyData { Name = Aus, ID = 1 } 
Console.WriteLine(obj);

// CANNOT CHANGE LATER - ERROR 
obj.Name = "US";

It is possible to create record structs. They should be used if the data to be stored is simple numeric.

A record struct is read-write by default. It can be made init-once by using the readonly keyword public readonly record struct MyData (int X, int Y);


// use record structs for simple numeric data 
// record structs are value types 

// readonly keyword is required if 
// the struct has to be init-once 
// otherwise it becomes read-write 

public readonly record struct MyData (int X, int Y);

Two objects of records and structs are equally if they contain the same values and are of the same type.

Two objects of classes are equal only if they point to the same object in heap memory.

When to use a record?

Now let me give a summary of when to use what.

A record should be used to hold init-once data that will never be changed. This is the working rule.

A record class is passed by reference but a record struct is passed by value.

Use a readonly record struct if the data is small and numeric type and init-once type. This ensures that objects are not created on the heap and are easier to pass by value.

Use a record class if the data contained is large, or it is complex like strings or other C# classes.

This is sufficient to get you started. But these are not easy concepts, they need a deeper study that can be done as you become more proficient in C# programming. Thanks!


This Blog Post/Article "(C# Language) class, record and struct" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.