7_Основные возможности System
Урок 7 : Основные возможности System
Пространство имён System содержит базовые инструменты C#: работу со строками, датами, математикой и случайными числами. Всё это используется в повседневном программировании.
1. System.Object - базовый класс всех классов
System.Object (сокращение - object) - корневой класс иерархии типов C#. Каждый класс неявно наследует его, даже если это не написано явно.
Три главных виртуальных метода
class Monster
{
public string Name;
public int Level;
}
Monster m = new Monster { Name = "Дракон", Level = 50 };
// ToString() - по умолчанию возвращает имя типа
Console.WriteLine(m.ToString()); // "Monster"
Console.WriteLine(m); // тоже вызывает ToString()
// Equals() - по умолчанию сравнивает ссылки
Monster a = new Monster { Name = "Орк" };
Monster b = new Monster { Name = "Орк" };
Console.WriteLine(a.Equals(b)); // false - разные объекты в памяти!
// GetHashCode() - целочисленный хеш объекта
Console.WriteLine(a.GetHashCode()); // некоторое число
Зачем переопределять эти методы?
class Item
{
public string Name { get; }
public int Price { get; }
public Item(string name, int price)
{
Name = name;
Price = price;
}
// Читаемое строковое представление
public override string ToString()
=> $"[{Name}] - {Price} монет";
// Логическое равенство по содержимому
public override bool Equals(object? obj)
{
if (obj is not Item other) return false;
return Name == other.Name && Price == other.Price;
}
// GetHashCode должен быть согласован с Equals:
// если Equals → true, то GetHashCode должен вернуть одно значение
public override int GetHashCode()
=> HashCode.Combine(Name, Price);
}
Item sword1 = new Item("Меч", 100);
Item sword2 = new Item("Меч", 100);
Console.WriteLine(sword1); // "[Меч] - 100 монет"
Console.WriteLine(sword1.Equals(sword2)); // true - теперь сравнивает по содержимому
// Корректная работа в коллекциях (Dictionary, HashSet)
var dict = new Dictionary<Item, int>();
dict[sword1] = 1;
Console.WriteLine(dict[sword2]); // 1 - найдёт по sword2, т.к. Equals и GetHashCode согласованы
Если переопределяете Equals - всегда переопределяйте GetHashCode. Иначе объекты не будут корректно работать в Dictionary, HashSet и других хеш-структурах.
2. String vs StringBuilder
string в C# - неизменяемый (immutable) тип. Каждая операция изменения создаёт новый объект в памяти.
Обычная строка - это чистовик: каждое «изменение» создаёт новый лист. StringBuilder - черновик: вы пишете, зачёркиваете, добавляете в одном месте. Только когда всё готово - переносите на чистый лист (ToString()).
Проблема с конкатенацией строк в цикле
// МЕДЛЕННО: каждый += создаёт новый объект string
string result = "";
for (int i = 0; i < 10_000; i++)
{
result += "Hello"; // 10_000 объектов в памяти!
}
StringBuilder - буфер для эффективного построения строк
using System.Text;
// БЫСТРО: StringBuilder меняет один внутренний буфер
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10_000; i++)
{
sb.Append("Hello");
}
string result = sb.ToString(); // конвертируем в string в конце
Методы StringBuilder
StringBuilder sb = new StringBuilder();
sb.Append("Привет"); // добавить в конец
sb.Append(", ");
sb.Append("мир");
sb.AppendLine("!"); // добавить + перевод строки
sb.Insert(0, ">> "); // вставить по индексу
sb.Replace("мир", "Unity"); // заменить подстроку
sb.Remove(0, 3); // удалить символы
Console.WriteLine(sb.Length); // количество символов
Console.WriteLine(sb.ToString()); // получить готовую строку
Когда что использовать
| Ситуация | Используйте |
|---|---|
| Собираете строку в цикле (100+ итераций) | StringBuilder |
| Небольшое число конкатенаций | string + $"" или string.Format |
| Финальный результат для вывода | string |
3. System.DateTime
DateTime - дата и время
// Текущее время системы
DateTime now = DateTime.Now; // локальное время
DateTime utcNow = DateTime.UtcNow; // UTC время
// Создание конкретной даты
DateTime release = new DateTime(2024, 11, 15, 12, 0, 0); // 15 ноября 2024, 12:00:00
// Форматирование
Console.WriteLine(now.ToString("dd.MM.yyyy HH:mm:ss")); // 22.02.2026 15:30:00
Console.WriteLine(now.ToString("yyyy-MM-dd")); // 2026-02-22
// Арифметика дат
DateTime tomorrow = now.AddDays(1);
DateTime nextMonth = now.AddMonths(1);
DateTime nextYear = now.AddYears(1);
TimeSpan diff = release - now; // разница между датами
Console.WriteLine($"До события: {diff.Days} дней");
// Свойства компонентов
Console.WriteLine(now.Year); // год
Console.WriteLine(now.Month); // месяц
Console.WriteLine(now.DayOfWeek);// день недели (например, Saturday)
TimeSpan - промежуток времени
TimeSpan duration = new TimeSpan(2, 30, 0); // 2 часа 30 минут
// Из секунд
TimeSpan fromSeconds = TimeSpan.FromSeconds(3661);
Console.WriteLine(fromSeconds.Hours); // 1
Console.WriteLine(fromSeconds.Minutes); // 1
Console.WriteLine(fromSeconds.Seconds); // 1
// Форматирование
Console.WriteLine(fromSeconds.ToString(@"hh\:mm\:ss")); // 01:01:01
Что такое UTC?
UTC (Coordinated Universal Time) - мировое время без часовых поясов. Все часовые пояса определяются смещением от UTC.
- Москва: UTC+3
- Лондон: UTC+0 (зимой)
- Нью-Йорк: UTC-5
DateTimeOffset - дата, время и часовой пояс
DateTime не хранит информацию о часовом поясе. DateTimeOffset решает эту проблему: он хранит дату, время и смещение от UTC в одном значении, что делает его надёжным при передаче данных между системами.
// DateTimeOffset хранит смещение явно
DateTimeOffset dto = DateTimeOffset.Now;
Console.WriteLine(dto); // 2026-04-11 15:30:00 +03:00
// Создание с явным смещением
DateTimeOffset moscow = new DateTimeOffset(2026, 4, 11, 15, 0, 0, TimeSpan.FromHours(3));
// Перевод в UTC
DateTimeOffset utc = dto.ToUniversalTime();
Console.WriteLine(utc.Offset); // 00:00:00
// Форматирование со смещением
Console.WriteLine(dto.ToString("yyyy-MM-dd HH:mm:ss zzz")); // 2026-04-11 15:30:00 +03:00
| Тип | Часовой пояс | Когда использовать |
|---|---|---|
DateTime |
Не хранит | Локальные расчёты, отображение в UI |
DateTimeOffset |
Хранит смещение | Базы данных, API, передача данных |
DateTime.UtcNow |
Всегда UTC | Внутренняя логика, серверы |
При сохранении или передаче дат между системами используйте DateTimeOffset или UTC. DateTime без явного часового пояса может дать неверный результат при работе в разных регионах.
4. System.Math
Статический класс с математическими функциями. Работает с double.
// Основные методы
Math.Abs(-15) // 15 - абсолютное значение
Math.Max(10, 20) // 20 - максимум
Math.Min(10, 20) // 10 - минимум
Math.Clamp(150, 0, 100) // 100 - ограничение в диапазоне [0, 100]
// Округление
Math.Round(3.7) // 4 - до ближайшего целого
Math.Floor(3.9) // 3 - вниз (пол)
Math.Ceiling(3.1) // 4 - вверх (потолок)
Math.Truncate(3.9) // 3 - отбросить дробную часть
// Степени и корни
Math.Pow(2, 10) // 1024 - возведение в степень
Math.Sqrt(144) // 12 - квадратный корень
Math.Cbrt(27) // 3 - кубический корень
// Тригонометрия (в радианах)
Math.Sin(Math.PI / 2) // 1.0
Math.Cos(0) // 1.0
double degrees = 45;
double radians = degrees * Math.PI / 180;
// Константы
Math.PI // 3.14159...
Math.E // 2.71828...
В Unity используется Mathf (вариант с float вместо double): Mathf.Clamp, Mathf.Lerp, Mathf.Sin и т.д. Принципы те же, но быстрее для игровых расчётов.
5. System.Random - псевдослучайные числа
Random rng = new Random(); // с системным seed (начальным значением)
Random seeded = new Random(42); // с фиксированным seed (воспроизводимый результат)
// Целые числа
int d6 = rng.Next(1, 7); // от 1 до 6 включительно (верхняя граница не включается!)
int percent = rng.Next(0, 101); // от 0 до 100
int anyInt = rng.Next(); // любое неотрицательное int
// Дробные числа
double d = rng.NextDouble(); // от 0.0 до 1.0 (не включая 1.0)
float f = (float)rng.NextDouble();
// Диапазон float
float range = 2.0f + (float)rng.NextDouble() * 8.0f; // от 2.0 до 10.0
// C# 6+: можно использовать как статический метод
int val = Random.Shared.Next(1, 101); // потокобезопасный глобальный экземпляр
Random - псевдослучайный генератор. Числа определяются начальным значением (seed). С одинаковым seed - одинаковая последовательность. Это полезно для воспроизводимых тестов, но не подходит для криптографии.
// Пример: случайный предмет из списка
List<string> loot = new List<string> { "Меч", "Щит", "Зелье", "Золото" };
string drop = loot[rng.Next(loot.Count)];
Console.WriteLine($"Выпал: {drop}");
// Пример: проверка шанса (30%)
bool triggered = rng.Next(100) < 30;
Итог урока
- System.Object:
ToString(),Equals(),GetHashCode()- переопределять вместе - StringBuilder: эффективное построение строк в циклах;
string- для обычных операций - DateTime: дата и время;
TimeSpan- промежутки; UTC - всемирное время без часовых поясов; DateTimeOffset - дата и время со смещением часового пояса, надёжен при передаче данных между системами - Math: математические функции;
Clamp,Lerp,Sqrt,Pow- часто используются в Unity - Random:
Next(min, max)- (min, max),NextDouble()- (0.0, 1.0)
📋 Перейти к практическим заданиям урока 7