Перегрузка операторов

Перегруженный оператор — это метод со специальными именами, где за ключевым словом operator следует символ переопределяемого оператора.

class Box {
  public int Height { get; set; }
  publci int Width { get; set; }
  public Box(int h, int w) {
    Height = h;
    Width = w;
  }

public static Box operator+ (Box a, Box b) {
  int h = a.Height + b.Height;
  int w = a.Width + b.Width;
  Box res = new Box(h, w);
  return res;
  }
}
static void Main(string[] args) {
  Box b1 = new Box(14, 3);
  Box b2 = new Box(5, 7);
  Box b3 = b1 + b2;
  Console.WriteLine(b3.Height); // 19
  Console.WriteLine(b3.Width); // 10
}

Благодаря этому перегруженному оператору мы суммируем сразу 2 параметра. Перегруженный оператор должен быть static.

Перегружены могут быть все арифметические операторы и операторы сравнения. При перегрузке оператора >, оператор < должен быть тоже перегружен (тип будет bool: public static bool operator>).

Классы: индексаторы

Объявление индексатора похоже на объявление свойства класса, разница лишь в том, что для индексатора нужен индекс. Как и в свойствах можно использовать элементы get и set. Однако, где свойства возвращают или устанавливают определенный элемент данных, индексаторы возвращают или устанавливают определенное значение объекта. Индексаторы определяются ключевым словом this.

class Clients {
  private sting[] names = new string[10];

  public string this[int index] {
    get {
      return names[index];
    }
    set {
      names[index] = value;
    }
  }
}

Теперь, когда мы объявили объект Clients, мы используем индекс для обращения к определенным объектам, типа элементов массива:

Clients c = new Clients();
c[0] = "David";
c[1] = "Zineddin";

Console.WriteLine(c[1]);
// Outouts "Zineddin"

Индексаторы используются, когда класс представляет собой список, коллекцию или массив объектов.

readonly vs const

Модификатор readonly защищает элементы класса от модификации после построения. Поле с readonly может быть модифицировано только при создании объекта класса или внутри конструктора.

3 отличия:

  1. Константа должна быть инициализирована при объявлении
  2. Readonly может быть модифицировано в конструкторе
  3. Readonly может быть присвоено значение, являющееся результатом вычислений

Static

Если переменная в классе статическая, то к ней из вне можно обратиться через имя класса:

ClassName.variable

Чтобы всегда можно было обратиться из вне, функция Main всегда статична. Константы тоже всегда статичны, там можно даже не указывать static.

Классы: деструкторы

Когда программа запускается, то сначала создается объект, выполняется конструктор. В конце программы конструктор удаляется, а деструктор вызывается.

class Dog {
  public Dog() {
    Console.WriteLine("Konstructor");
  }
  ~Dog() {
    Console.WriteLine("Destructor");
  }
}

static void Main(string[] args) {
  Dog d = new Dog();
}

/* Outputs:
Constructor
Destructor
*/

Работа со строками в C#

string a = "Some text";
ConsoleWriteLine(a.Lenght);
//9

ConsoleWriteLine(a.IndexOf('t'));
//5

a = a.Insert(0, "This is ");
ConsoleWriteLine(a);
//This is Some text

a = a.Replace("This is", "I am");
ConsoleWriteLine(a);
//I am Some text

if(a.Contains("some"))
  ConsoleWriteLine("found");
//found

a = a.Remove(4);
ConsoleWriteLine(a);
//I am

a = a.Substring(2);
ConsoleWriteLine(a);
//am

Классы: свойства

Инкапсуляция дает доступ только через публичные методы, а свойства дают возможность реализации гибкого механизма чтения, записи и вычисления приватного поля. Свойства используют элементы доступа get, set.

class Person {
  private string name;
  public string Name {
    get { return name; }
    set { name = value; } // тут можно прописать условия, а не просто присваивание
    }
  }

// Закомментированный код ниже заменяет весь код внутри класса Person
// public string Name { get; set; }

static void Main(string[] args) {
  Person p = new Person();
  p.Name = "Bobik";
  Console.WriteLine(p.Name);
  }

Свойства могут называться как угодно, но принято для понимания кода называть их по имени переменной, но только с большой буквы: name => Name.

Также есть автоматически реализуемые свойства (краткая запись, если нет необходимости реализовать логику в set).

public string Name { get; set; }

Классы: конструктор

Если при создании нового объекта класса нужно что-то автоматически сделать (например, вывести текст, отправить смс) используются конструкторы класса.

class Person {
  private int age;
  public Person() {
    Console.WriteLine("Привет!");
    }
  }

Конструктор имеет такое же имя, что и класс, является публичным и не имеет никакого возвращаемого типа.

При создании объекта класса, реализованного выше Person p = new Person(), будет выведено сообщение «Привет!».