0Pricing
C# Academy · Урок

Инкапсуляция и инварианты

Скрывайте внутреннее состояние, предоставляйте безопасные операции и сохраняйте истинность инвариантов класса (например, неотрицательный баланс и допустимые диапазоны).

«Инкапсуляция и инварианты» — бесплатный урок C# Academy на CoddyKit. Это урок 3 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 3 уроков всего.

Обзор инкапсуляции

Цель: Защитить состояние объекта.

  • Инкапсуляция: скрывать fields и предоставлять безопасные APIs
  • Инвариант: правило, которое всегда выполняется
  • Проверяйте данные в конструкторах, set и methods

Интерфейс только для чтения

Храните fields как private. Предоставляйте вызывающему коду свойство только для чтения и безопасные операции.

using System;

// Expose read-only view; mutate via methods only
public class Counter
{
  private int _value;          // hidden state
  public int Value             // read-only to callers
  {
    get { return _value; }
    private set { _value = value; } // keep setter private
  }

  public void Increment()
  {
    Value = Value + 1;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    Counter c = new Counter();
    c.Increment();
    c.Increment();
    Console.WriteLine("Value = " + c.Value);
  }
}

Проверки в конструкторах

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

using System;

// Enforce rules early (constructor guard)
public class User
{
  public string Name { get; private set; }
  public int Age { get; private set; }

  public User(string name, int age)
  {
    if (string.IsNullOrEmpty(name)) throw new ArgumentException("name");
    if (age < 0) throw new ArgumentOutOfRangeException("age");
    Name = name;
    Age = age;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    try
    {
      User u = new User("Ada", 28);
      Console.WriteLine(u.Name + " (" + u.Age + ")");
    }
    catch (Exception ex)
    {
      Console.WriteLine("Error: " + ex.Message);
    }
  }
}

Инвариант на практике

Определите инвариант (например, Balance ≥ 0) и обеспечивайте его выполнение в set и methods.

using System;

// Invariant: Balance >= 0 at all times
public class BankAccount
{
  private decimal _balance;

  public decimal Balance
  {
    get { return _balance; }
    private set
    {
      if (value < 0) throw new InvalidOperationException("Balance would be negative");
      _balance = value;
    }
  }

  public BankAccount(decimal opening)
  {
    if (opening < 0) throw new ArgumentOutOfRangeException("opening");
    _balance = opening;
  }

  public void Deposit(decimal amount)
  {
    if (amount <= 0) throw new ArgumentOutOfRangeException("amount");
    Balance = Balance + amount;
  }

  public bool TryWithdraw(decimal amount)
  {
    if (amount <= 0) return false;
    if (Balance - amount < 0) return false;
    Balance = Balance - amount;
    return true;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    BankAccount a = new BankAccount(50m);
    a.Deposit(20m);
    bool ok = a.TryWithdraw(100m); // fails, invariant protected
    Console.WriteLine("ok=" + ok + " balance=" + a.Balance);
  }
}

Защита коллекций

Не предоставляйте внутренние списки и массивы напрямую. Возвращайте копию (или представление только для чтения), чтобы защищать инварианты.

using System;
using System.Collections.Generic;

public class Tags
{
  private readonly List<string> _items = new List<string>();

  public void Add(string tag)
  {
    if (string.IsNullOrWhiteSpace(tag)) return;
    _items.Add(tag.Trim());
  }

  // Expose a copy so callers cannot mutate internal list
  public List<string> GetAllCopy()
  {
    return new List<string>(_items);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    Tags t = new Tags();
    t.Add(" apple ");
    t.Add("banana");
    List<string> view = t.GetAllCopy();
    view.Add("hacker"); // modifies the copy only
    Console.WriteLine("copy count=" + view.Count);
    Console.WriteLine("original count=" + t.GetAllCopy().Count);
  }
}

Советы по инкапсуляции

Чек-лист:

  • Закрытые fields; общедоступные properties и methods.
  • Проверяйте данные в конструкторах и set.
  • Поддерживайте истинность инвариантов после каждого вызова.
  • Не раскрывайте внутренние коллекции.

Принцип инкапсуляции

Быстрая проверка: какой выбор лучше всего сохраняет инкапсуляцию и инвариант класса?

Итоги

Итоги: Инкапсулируйте данные с помощью закрытых fields и APIs с проверкой. Определяйте инвариант и обеспечивайте его выполнение в конструкторах, set и methods. Никогда не раскрывайте внутренние коллекции.

Часто задаваемые вопросы

Урок «Инкапсуляция и инварианты» бесплатный?

Да — полный текст урока «Инкапсуляция и инварианты» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 3 уроков всего.

Чему я научусь в уроке «Инкапсуляция и инварианты»?

Скрывайте внутреннее состояние, предоставляйте безопасные операции и сохраняйте истинность инвариантов класса (например, неотрицательный баланс и допустимые диапазоны). Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 3.

Сколько времени занимает урок «Инкапсуляция и инварианты»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Поля, автоматически реализуемые свойства, инициализаторы объектов
  2. Конструкторы и статические члены
  3. Инкапсуляция и инварианты
← Назад к C# Academy