7. Namespaces

Namespaces

Namespaces in C# provide a way to organize and group related classes, interfaces, structs, and other types. They also help resolve naming conflicts when two or more classes share the same name. By placing classes into different namespaces, you avoid collisions and keep your code logically structured.

namespace ProjectA.Common
{
    public class Utility
    {
        public static void DoSomething() {}
    }
}

namespace ProjectB.Common
{
    public class Utility
    {
        public static void DoSomethingElse() {}
    }
}

Here, each Utility class resides in a different namespace (ProjectA.Common and ProjectB.Common). Clients of these classes can use fully qualified names or using directives to distinguish between them.

Operator Overloading

Operator overloading allows you to redefine how operators work with your own custom classes or structs. This enables you to write expressions such as obj1 + obj2 or obj1 == obj2, where obj1 and obj2 are instances of a user-defined type.

Basic Syntax

public class ComplexNumber
{
    public double Real { get; set; }
    public double Imaginary { get; set; }

    public ComplexNumber(double real, double imaginary)
    {
        Real = real;
        Imaginary = imaginary;
    }

    // Overload the + operator
    public static ComplexNumber operator +(ComplexNumber c1, ComplexNumber c2)
    {
        return new ComplexNumber(c1.Real + c2.Real, c1.Imaginary + c2.Imaginary);
    }

    // Overload the == operator
    public static bool operator ==(ComplexNumber c1, ComplexNumber c2)
    {
        return (c1.Real == c2.Real) && (c1.Imaginary == c2.Imaginary);
    }

    // Overload the != operator
    public static bool operator !=(ComplexNumber c1, ComplexNumber c2)
    {
        return !(c1 == c2);
    }

    // Always override Equals() and GetHashCode() when overloading equality operators
    public override bool Equals(object obj)
    {
        if (obj is ComplexNumber other)
        {
            return this == other;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return Real.GetHashCode() ^ Imaginary.GetHashCode();
    }
}

In this example, the + operator allows you to add two ComplexNumber objects using c1 + c2. Overloading the == and != operators provides custom equality checks. When you do this, it’s recommended to override Equals and GetHashCode to maintain consistency.

Benefits of Operator Overloading

However, be cautious. Overzealous operator overloading can confuse other developers if the meaning of an operator strays too far from its conventional behavior.

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