8. Indexer, Inheritance

Readonly Fields vs. const in C#

In C#, both readonly and const are used to create fields that should not change after initial assignment. However, they differ in when and how their values are set:

Example: Readonly vs. const

public class Configuration
{
    public const int MaxItems = 100;                // set at compile time
    public readonly int LaunchYear;                 // set in constructor

    public Configuration(int year)
    {
        LaunchYear = year; // can only be assigned here or at declaration
    }

    // LaunchYear cannot be changed in any other method
}

In the example, MaxItems is a compile-time constant, while LaunchYear can be different depending on the constructor’s argument, yet becomes immutable after that point.

Guid (Global Unique Identifier)

A Guid is a 128-bit struct that provides a virtually unique code, commonly used for identifiers (e.g., for database primary keys, unique tokens, etc.). The probability of generating the same Guid twice is astronomically low (about 1 in 2^122).

public void GenerateGuid()
{
    Guid newId = Guid.NewGuid();
    Console.WriteLine($"Your new Guid: {newId}");
}

Every time Guid.NewGuid() is called, it produces a brand-new code guaranteed (practically) not to collide with any other.

Single Inheritance in C#

C# allows a class to inherit from only one direct base class. This restriction is known as single inheritance. Although you cannot inherit from multiple classes, you can implement multiple interfaces.

public class BaseClass
{
    public void BaseMethod()
    {
        Console.WriteLine("Method in the base class.");
    }
}

public class DerivedClass : BaseClass
{
    public void DerivedMethod()
    {
        Console.WriteLine("Method in the derived class.");
    }
}

// Usage
var derived = new DerivedClass();
derived.BaseMethod();     // from BaseClass
derived.DerivedMethod();  // from DerivedClass

Multiple inheritance (inheriting from more than one base class) is not supported in C#.

Hiding Methods with the new Keyword

Sometimes a derived class has a method with the same signature as one in its base class. To explicitly hide the base class method, use the new keyword:

public class BaseClass
{
    public void Show()
    {
        Console.WriteLine("BaseClass.Show()");
    }
}

public class DerivedClass : BaseClass
{
    // new keyword hides the base class method
    public new void Show()
    {
        Console.WriteLine("DerivedClass.Show()");
    }
}

public static void DemoHideMethod()
{
    DerivedClass obj = new DerivedClass();
    obj.Show(); // Calls DerivedClass.Show()

    BaseClass baseRef = obj;
    baseRef.Show(); // Calls BaseClass.Show(), because new hides the method rather than overriding it
}

This approach “shadows” the base class method within the derived class. It is most useful when you want the same method name but do not want polymorphic behavior.

Sealed Classes

A class marked with sealed cannot be inherited by any other class. Use this if you want to prevent further specialization or extension of your class’s behavior.

public sealed class FinalClass
{
    public void DisplayMessage()
    {
        Console.WriteLine("This class cannot be inherited from.");
    }
}

// The following would cause a compile-time error:
// public class AttemptedDerivation : FinalClass {}

Sealing a class can help maintain strict control over its usage or protect it from unintended inheritance scenarios.

Reference

The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:

Original Note - Azerbaijani Version