Экземплярные и статические данные
Часть раздела Объектно-ориентированное программирование путешествия по C# на Coddy — урок 15 из 70.
Теперь, когда вы понимаете статические члены, давайте проясним, когда использовать данные экземпляра, а когда статические данные. Это решение определяет то, как ваш класс хранит и передает информацию.
Данные экземпляра принадлежат каждому объекту индивидуально. Каждый объект получает свою собственную копию, и изменения в одном объекте не влияют на другие:
public class BankAccount
{
public string Owner { get; set; } // Экземпляр — уникально для каждого счета
public decimal Balance { get; set; } // Экземпляр — уникально для каждого счета
}У каждого BankAccount есть свой владелец и баланс. Это логично, так как разные счета содержат разные суммы для разных людей.
Статические данные принадлежат самому классу и являются общими для всех экземпляров:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // Статическое — одинаково для всех
public static int TotalAccounts = 0; // Статическое — отслеживает все счета
public string Owner { get; set; }
public decimal Balance { get; set; }
}Процентная ставка применяется одинаково к каждому счету, поэтому логично сделать её статической (static). Общий счетчик аккаунтов отслеживает информацию на уровне всего класса, а не данные конкретного счета.
Простое правило: если данные описывают конкретный объект, сделайте их полями экземпляра (instance). Если они описывают класс в целом или должны быть общими, сделайте их статическими (static). Неправильное их смешивание приводит к ошибкам, при которых данные неожиданно меняются во всех объектах или становятся недоступны в нужный момент.
Задание
ЛегкоДавайте создадим трекер игровой сессии, который демонстрирует разницу между данными, принадлежащими отдельным игрокам, и данными, общими для всей игры.
Вы создадите два файла для организации вашего кода:
Player.cs: Определите классPlayerв пространстве именGameSession. У каждого игрока есть свои собственныеUsername(string) иScore(int) — они уникальны для каждого игрока. Класс также должен отслеживать информацию, которая относится ко всем игрокам: статическое полеGameName(string), в котором хранится название игры, в которую все играют, и статическое полеTotalPlayers(int), которое подсчитывает, сколько игроков присоединилось. Включите конструктор, который принимает имя пользователя и начальный счет и автоматически увеличивает общее количество игроков. Добавьте статический методSetGameName(string name)для настройки названия игры.Program.cs: В основном файле настройте игру и создайте игроков на основе входных данных. Сначала установите название игры, затем создайте двух игроков и выведите их индивидуальную информацию вместе с общими данными игры.
Вы получите пять входных данных:
- Название игры
- Имя пользователя первого игрока
- Начальный счет первого игрока
- Имя пользователя второго игрока
- Начальный счет второго игрока
Выведите результат в следующем формате:
Game: {GameName}
Player: {Username}, Score: {Score}
Player: {Username}, Score: {Score}
Total Players: {TotalPlayers}Например, если входные данные — BattleArena, DragonSlayer, 1500, ShadowNinja и 2200, вывод должен быть следующим:
Game: BattleArena
Player: DragonSlayer, Score: 1500
Player: ShadowNinja, Score: 2200
Total Players: 2Подумайте внимательно о том, какие данные должны быть привязаны к экземпляру (разные для каждого игрока), а какие должны быть статическими (общими для всех игроков). Название игры и общее количество игроков описывают сессию в целом, в то время как имя пользователя и счет уникальны для каждого отдельного человека.
Шпаргалка
Используйте данные экземпляра для свойств, которые уникальны для каждого объекта:
public class BankAccount
{
public string Owner { get; set; } // У каждого счета свой владелец
public decimal Balance { get; set; } // У каждого счета свой баланс
}Используйте статические данные для свойств, общих для всех экземпляров класса:
public class BankAccount
{
public static decimal InterestRate = 0.05m; // Одинаково для всех счетов
public static int TotalAccounts = 0; // Отслеживает все счета
public string Owner { get; set; }
public decimal Balance { get; set; }
}Правило принятия решения: Если данные описывают конкретный объект, используйте данные экземпляра. Если они описывают класс в целом или должны быть общими, используйте статические данные.
Попробуйте сами
using System;
namespace GameSession
{
class Program
{
public static void Main(string[] args)
{
// Чтение входных данных
string gameName = Console.ReadLine();
string username1 = Console.ReadLine();
int score1 = Convert.ToInt32(Console.ReadLine());
string username2 = Console.ReadLine();
int score2 = Convert.ToInt32(Console.ReadLine());
// TODO: Установите название игры, используя статический метод
// TODO: Создайте два объекта Player с входными данными
// TODO: Выведите результат в требуемом формате
// Game: {GameName}
// Player: {Username}, Score: {Score}
// Player: {Username}, Score: {Score}
// Total Players: {TotalPlayers}
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыПространства имен и директивыВведение в классы и объектыКлючевое слово 'this'Методы и параметрыПоля и свойстваКонструкторыИнициализаторы объектовИтоги — Простой калькулятор4Наследование
Основы синтаксиса наследования (:)Ключевое слово 'base'Ключевые слова Virtual и OverrideЗапечатанные классыБазовый класс 'object'Итоги — Иерархия сотрудников7Продвинутые возможности
Перегрузка операторовИндексаторы (this[])Переопределение ToString()Методы расширенияПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПотокобезопасный SingletonПаттерн FactoryПаттерн Observer (События)Паттерн Strategy13Финальные испытания
Платформа для онлайн-обученияКомпонент игрового персонажаСервис аренды транспорта2Свойства и статические члены
Автоматически реализуемые свойстваСвойства только для чтения и записиСтатические поля и методыСтатические классыЧлены в виде выражений5Полиморфизм и интерфейсы
Полиморфизм: компиляция vs выполнениеИнтерфейс vs абстрактный классМножественные интерфейсыЯвные интерфейсыUpcasting и DowncastingИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция вместо наследованияGenerics (классы и методы)Делегаты и событияАтрибуты и рефлексияIDisposable и оператор usingОсновы Dependency Injection11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Архитектура классов
Экземплярные и статические данныеКлючевые слова 'readonly' и 'const'Опорные поляПовторение — Менеджер банковских счетов6Инкапсуляция
Модификаторы доступаСвойства для инкапсуляцииРеализация скрытия данныхПаттерны неизменяемостиИтоги — Записи студентов9Переменное количество аргументов
Ключевое слово 'params'Необязательные параметрыИменованные аргументыПерегрузка методов