Выбрать главу

public Employee(string name, int age, int id, float pay)

{

   // Уже лучше! Используйте свойства для установки данных класса.

   // Это сократит количество дублированных проверок на предмет ошибок.

   Name = name;

   Age = age;

   ID = id;

   Pay = pay;

}

Помимо обновления конструкторов для применения свойств при присваивании значений рекомендуется повсюду в реализации класса использовать свойства, чтобы гарантировать неизменное соблюдение бизнес-правил. Во многих случаях прямая ссылка на лежащие в основе закрытые данные производится только внутри самого свойства. Имея все сказанное в виду, модифицируйте класс Employee:

class Employee

{

  // Поля данных.

  private string _empName;

  private int _empId;

  private float _currPay;

  private int _empAge;

  // Конструкторы.

  public Employee() { }

  public Employee(string name, int id, float pay)

    :this(name, 0, id, pay){}

  public Employee(string name, int age, int id, float pay)

  {

    Name = name;

    Age = age;

    ID = id;

    Pay = pay;

  }

  // Методы.

  public void GiveBonus(float amount) => Pay += amount;

  public void DisplayStats()

  {

    Console.WriteLine("Name: {0}", Name); // имя сотрудника

    Console.WriteLine("ID: {0}", Id);

                    // идентификационный номер сотрудника

    Console.WriteLine("Age: {0}", Age);   // возраст сотрудника

    Console.WriteLine("Pay: {0}", Pay);   // текущая выплата

  }

  // Свойства остаются прежними...

  ...

}

Свойства, допускающие только чтение

При инкапсуляции данных может возникнуть желание сконфигурировать свойство, допускающее только чтение, для чего нужно просто опустить блок set. Например, пусть имеется новое свойство по имени SocialSecurityNumber, которое инкапсулирует закрытую строковую переменную empSSN. Вот как превратить его в свойство, доступное только для чтения:

public string SocialSecurityNumber

{

  get { return _empSSN; }

}

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

public string SocialSecurityNumber => _empSSN;

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

public Employee(string name, int age, int id, float pay, string ssn)

{

   Name = name;

   Age = age;

   ID = id;

   Pay = pay;

   // Если свойство предназначено только для чтения, это больше невозможно!

   SocialSecurityNumber = ssn;

}

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

public Employee(string name, int age, int id, float pay, string ssn)

{

   ...

   // Проверить надлежащим образом входной параметр ssn

   // и затем установить значение.

   empSSN = ssn;

}

Свойства, допускающие только запись

 Если вы хотите сконфигурировать свойство как допускающее только запись, тогда опустите блок get, например:

public int Id

{

  set { _empId = value; }

}