<commit_before># Classes

<!-- TOC -->

- [Classes](#classes)
  - [Members](#members)
  - [Модификаторы доступа](#Модификаторы-доступа)
  - [Конструкторы](#Конструкторы)
  - [Methods](#methods)
    - [Local functions (TODO)](#local-functions-todo)
  - [Properties](#properties)
  - [`readonly`](#readonly)
  - [`const`](#const)
  - [`static`](#static)
    - [`static` member](#static-member)
    - [`static` class](#static-class)
    - [`static` конструктор](#static-конструктор)
  - [`partial`](#partial)
  - [Наследование, полиморфизм](#Наследование-полиморфизм)
    - [`sealed`](#sealed)
    - [`abstract`](#abstract)
  - [Interface](#interface)
  - [Перегрузка операторов](#Перегрузка-операторов)
    - [Перегрузка преобразований типов](#Перегрузка-преобразований-типов)
  - [Extension methods](#extension-methods)
  - [Аттрибуты](#Аттрибуты)

<!-- /TOC -->

<div style="page-break-after: always;"></div>

## Members

[Члены класса](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/members)

```cs
using System;
internal class SomeType
{
    private class SomeNestedType { }    // Nested Type

    private int _x = 1;                 // Field
    private SomeNestedType Value;       // --

    internal SomeType(Int32 x) { }      // Конструкторы экземпляров

    internal protected void Method() {} // Method
    internal int Property { get;set;}   // Property
}
```

<div style="page-break-after: always;"></div>

## Модификаторы доступа

Определяют видимость элемента

- `public` - доступен в любых сборках
- `internal` - только в текущей сборке
- `private` - только в данном классе
- `protected` - в классе и его наследниках
- `protected internal` - в классе и его наследниках из данной сборки

Можно определить сборку [дружественной](https://msdn.microsoft.com/en-us/library/0tke9fxk(v=vs.100).aspx), чтобы internal можно было использовать в другой сборке.

- По-умолчанию, если не указать будет private
- Проверку доступа производит как базовый компилятор, так и JIT компилятор
- При наследовании от базового класса CLR позволяет снижать, но не повышать ограничения доступа к члену.

<div style="page-break-after: always;"></div>

## Конструкторы

Все объекты создаются оператором `new`.

```cs
SomeType e = new SomeType(4);
SomeType e = new SomeType(3) { SomeProp = 5 }; // Инициализатор

e.SomeProp = 5  // Идентично
```

- Вычесляет количество необходимой памяти для экземпляра
- Выделяет память в куче, заполняя нулями
- Инициализирует указатель на объект
- Вызывает конструктор с параметрами
- Возвращает ссылку на созданный объект

<div style="page-break-after: always;"></div>

У каждого managed объекта есть некоторый overhead:

![Managed object layout](pics/managed-object-layout.png)

- object header - used by clr
- “Why the managed object’s layout is so weird?”, is simple: “historical reasons” [MSDN blog post](https://blogs.msdn.microsoft.com/seteplia/2017/05/26/managed-object-internals-part-1-layout/)<commit_msg>classes - дописал про проблему, где определять уровень доступа на уровне класса или метода<commit_after># Classes

<!-- TOC -->

- [Classes](#classes)
  - [Members](#members)
  - [Модификаторы доступа](#access-modifiers)
  - [Конструкторы](#Конструкторы)
  - [Methods](#methods)
    - [Local functions (TODO)](#local-functions-todo)
  - [Properties](#properties)
  - [`readonly`](#readonly)
  - [`const`](#const)
  - [`static`](#static)
    - [`static` member](#static-member)
    - [`static` class](#static-class)
    - [`static` конструктор](#static-конструктор)
  - [`partial`](#partial)
  - [Наследование, полиморфизм](#Наследование-полиморфизм)
    - [`sealed`](#sealed)
    - [`abstract`](#abstract)
  - [Interface](#interface)
  - [Перегрузка операторов](#Перегрузка-операторов)
    - [Перегрузка преобразований типов](#Перегрузка-преобразований-типов)
  - [Extension methods](#extension-methods)
  - [Аттрибуты](#Аттрибуты)

<!-- /TOC -->

<div style="page-break-after: always;"></div>

## Members

[Члены класса](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/members)

```cs
using System;
internal class SomeType
{
    private class SomeNestedType { }    // Nested Type

    private int _x = 1;                 // Field
    private SomeNestedType Value;       // --

    internal SomeType(Int32 x) { }      // Конструкторы экземпляров

    internal protected void Method() {} // Method
    internal int Property { get;set;}   // Property
}
```

<div style="page-break-after: always;"></div>

## Access Modifiers

Модификаторы доступа определяют видимость элемента [MSDN](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers)

- `public` - доступен в любых сборках
- `internal` - только в текущей сборке
- `private` - только в данном классе
- `protected` - в классе и его наследниках
- `protected internal` - в классе и его наследниках из данной сборки

Можно определить сборку [дружественной](https://msdn.microsoft.com/en-us/library/0tke9fxk(v=vs.100).aspx), чтобы internal можно было использовать в другой сборке.

- По-умолчанию, если не указать, будет private.
- Рекомендуется всегда явно указывать!
- Проверку доступа производит как базовый компилятор, так и JIT компилятор
- При наследовании от базового класса CLR позволяет снижать, но не повышать ограничения доступа к члену.

<div style="page-break-after: always;"></div>

Насущный вопрос, если объявить класс `internal`, то с какой областью видимости объявлять методы/объекты в нём? `private` / `internal`.

- ! clr автоматически урежет права для экземплярных методов до уровня класса
  - исключения составляют `public` методы реализации интерфейсов или override методов публичного базового класса
- распространенная практика: задавать область видимость на уровне класса, а методы объявлять всегда `public`. Это [дискуссионный момент](https://stackoverflow.com/questions/9302236/why-use-a-public-method-in-an-internal-class), основной аргумент "за":
  - видимость для класса и его методов определяется в одном месте и это проще

```cs
internal static class Helper
{
    public static string Test() { return "Test"; }
}
```

<div style="page-break-after: always;"></div>

## Конструкторы

Все объекты создаются оператором `new`.

```cs
SomeType e = new SomeType(4);
SomeType e = new SomeType(3) { SomeProp = 5 }; // Инициализатор

e.SomeProp = 5  // Идентично
```

- Вычесляет количество необходимой памяти для экземпляра
- Выделяет память в куче, заполняя нулями
- Инициализирует указатель на объект
- Вызывает конструктор с параметрами
- Возвращает ссылку на созданный объект

<div style="page-break-after: always;"></div>

У каждого managed объекта есть некоторый overhead:

![Managed object layout](pics/managed-object-layout.png)

- object header - used by clr
- “Why the managed object’s layout is so weird?”, is simple: “historical reasons” [MSDN blog post](https://blogs.msdn.microsoft.com/seteplia/2017/05/26/managed-object-internals-part-1-layout/)
{'fraction_non_alphanumeric': 0.13394390383514596, 'fraction_numerical': 0.0070120206067544365, 'mean_word_length': 4.112655449890271, 'pattern_counts': {'":': 1, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4185569', 'n_tokens_mistral': 2647, 'n_tokens_neox': 2896, 'n_words': 585}