СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Свойства как специальные методы доступа в С#

Категория: Информатика

Нажмите, чтобы узнать подробности

Данный методический материал содержит презентацию к уроку "Свойства как специальные методы доступа в С#". Материал предназначен для подготовки к занятиям по данной теме, а также  для студентов, изучающих язык С# в дисциплинах "Основы алгоритмизации и программирования" и "Прикладное программирование". 

Просмотр содержимого документа
«Свойства как специальные методы доступа в С#»

Специальные методы доступа в С # .

Специальные методы доступа в С # .

Свойства  Кроме обычных методов в языке C# предусмотрены специальные методы доступа, которые называют  свойства . Они обеспечивают простой доступ к полям класса, узнать их значение или выполнить их установку.  Стандартное описание свойства имеет следующий синтаксис:  [атрибуты] [спецификаторы] тип имя_свойства{ [get код_доступа] [set код_доступа]}  Значения спецификаторов для свойств и методов аналогичны. Чаще всего свойства объявляются как открытые (со спецификатором public ).

Свойства

Кроме обычных методов в языке C# предусмотрены специальные методы доступа, которые называют  свойства . Они обеспечивают простой доступ к полям класса, узнать их значение или выполнить их установку.

Стандартное описание свойства имеет следующий синтаксис:

[атрибуты] [спецификаторы] тип имя_свойства{ [get код_доступа] [set код_доступа]}

Значения спецификаторов для свойств и методов аналогичны. Чаще всего свойства объявляются как открытые (со спецификатором public ).

 Стандартное определение свойства содержит блоки  get  и   set. В блоке get мы возвращаем значение поля, а в блоке set устанавливаем. class Person {      private string name;      public string Name      {          get          {              return name;          }          set          {              name = value;          }      } } Параметр value представляет передаваемое значение.

Стандартное определение свойства содержит блоки  get  и   set. В блоке get мы возвращаем значение поля, а в блоке set устанавливаем.

class Person

{

     private string name;

     public string Name

     {

         get

         {

             return name;

         }

         set

         {

             name = value;

         }

     }

}

Параметр value представляет передаваемое значение.

 Здесь поле name  закрытое и свойство Name общедоступное. Хотя они имеют практически одинаковое название за исключением регистра, но названия у них могут быть произвольные и не обязательно должны совпадать.  Через это свойство мы можем управлять доступом к переменной name.  Можно использовать данное свойство следующим образом: Person p = new Person(); // Устанавливаем свойство - срабатывает блок Set // значение

Здесь поле name  закрытое и свойство Name общедоступное. Хотя они имеют практически одинаковое название за исключением регистра, но названия у них могут быть произвольные и не обязательно должны совпадать.

Через это свойство мы можем управлять доступом к переменной name.

Можно использовать данное свойство следующим образом:

Person p = new Person();

// Устанавливаем свойство - срабатывает блок Set

// значение "Tom" и есть передаваемое в свойство value

p.Name = "Tom";

// Получаем значение свойства и //присваиваем его переменной - срабатывает блок Get string personName = p.Name;   Может возникнуть вопрос, зачем нужны свойства, если мы можем в данной ситуации обходиться обычными полями класса? Но свойства позволяют вложить дополнительную логику, которая может быть необходима, например, при присвоении переменной класса какого-либо значения.  Например, нам надо установить проверку по возрасту: class Person {      private int age;      public int Age     

// Получаем значение свойства и

//присваиваем его переменной - срабатывает блок Get

string personName = p.Name;

Может возникнуть вопрос, зачем нужны свойства, если мы можем в данной ситуации обходиться обычными полями класса? Но свойства позволяют вложить дополнительную логику, которая может быть необходима, например, при присвоении переменной класса какого-либо значения.

Например, нам надо установить проверку по возрасту:

class Person

{

     private int age;

     public int Age

    

     {          set          {              if (value              {                  Console.WriteLine(

     {

         set

         {

             if (value

             {

                 Console.WriteLine("Возраст должен быть больше 17");

             }

             else

             {

                 age = value;

             }

         }

         get { return age; }

     }

}

 Блоки set и get не обязательно одновременно должны присутствовать в свойстве. Если свойство определяют только блок get, то такое свойство доступно только для чтения - мы можем получить его значение, но не установить.  И, наоборот, если свойство имеет только блок set, тогда это свойство доступно только для записи - можно только установить значение, но нельзя получить: class Person {      private string name;      // свойство только для чтения      public string Name      {          get          {              return name;          }      }

Блоки set и get не обязательно одновременно должны присутствовать в свойстве. Если свойство определяют только блок get, то такое свойство доступно только для чтения - мы можем получить его значение, но не установить.

И, наоборот, если свойство имеет только блок set, тогда это свойство доступно только для записи - можно только установить значение, но нельзя получить:

  • class Person
  • {
  •      private string name;
  •      // свойство только для чтения
  •      public string Name
  •      {
  •          get
  •          {
  •              return name;
  •          }
  •      }
  private int age;      // свойство только для записи      public int Age      {          set          {              age = value;          }      } }  Можно применять модификаторы доступа не только ко всему свойству, но и к отдельным блокам - либо get, либо set:

  private int age;

     // свойство только для записи

     public int Age

     {

         set

         {

             age = value;

         }

     }

}

Можно применять модификаторы доступа не только ко всему свойству, но и к отдельным блокам - либо get, либо set:

class Person {      private string name;        public string Name      {          get          {              return name;          }            private set          {              name = value;          }      }      public Person(string name, int age)      {          Name = name;          Age = age;      } }
  • class Person
  • {
  •      private string name;
  •  
  •      public string Name
  •      {
  •          get
  •          {
  •              return name;
  •          }
  •  
  •          private set
  •          {
  •              name = value;
  •          }
  •      }
  •      public Person(string name, int age)
  •      {
  •          Name = name;
  •          Age = age;
  •      } }
 Теперь закрытый блок set можно использовать только в данном классе - в его методах, свойствах, конструкторе, но никак не в другом классе: Person p = new Person(

Теперь закрытый блок set можно использовать только в данном классе - в его методах, свойствах, конструкторе, но никак не в другом классе:

Person p = new Person("Tom", 24); 

// Ошибка - set объявлен с модификатором private

//p.Name = "John"; 

Console.WriteLine(p.Name);

При использовании модификаторов в свойствах следует учитывать ряд ограничений:

  • Модификатор для блока set или get можно установить, если свойство имеет оба блока (и set, и get).
  • Только один блок set или get может иметь модификатор доступа, но не оба сразу.
Модификатор доступа блока set или get должен быть более ограничивающим, чем модификатор доступа свойства. Например, если свойство имеет модификатор public, то блок set/get может иметь только модификаторы protected internal, internal, protected, private.  Инкапсуляция  Через свойства можно установить доступ к приватным переменным класса. Подобное сокрытие состояния класса от вмешательства извне представляет механизм  инкапсуляции .  Применение модификаторов доступа типа private защищает переменную от внешнего доступа. Для управления доступом во многих языках программирования используются специальные методы, геттеры и сеттеры. В C# их роль выполняют свойства.
  • Модификатор доступа блока set или get должен быть более ограничивающим, чем модификатор доступа свойства. Например, если свойство имеет модификатор public, то блок set/get может иметь только модификаторы protected internal, internal, protected, private.

Инкапсуляция

Через свойства можно установить доступ к приватным переменным класса. Подобное сокрытие состояния класса от вмешательства извне представляет механизм  инкапсуляции .

Применение модификаторов доступа типа private защищает переменную от внешнего доступа. Для управления доступом во многих языках программирования используются специальные методы, геттеры и сеттеры. В C# их роль выполняют свойства.

 Например, есть некоторый класс Account , в котором определено поле sum, представляющее сумму:  class Account {      public int sum; }  Так как переменная sum является публичной, то в любом месте программы можно получить к ней доступ и изменить ее, в том числе установить какое-либо недопустимое значение, например, отрицательное. А это не является желательным. Поэтому применяется инкапсуляция для ограничения доступа к переменной sum и сокрытию ее внутри класса:

Например, есть некоторый класс Account , в котором определено поле sum, представляющее сумму:

class Account

{

     public int sum;

}

Так как переменная sum является публичной, то в любом месте программы можно получить к ней доступ и изменить ее, в том числе установить какое-либо недопустимое значение, например, отрицательное. А это не является желательным. Поэтому применяется инкапсуляция для ограничения доступа к переменной sum и сокрытию ее внутри класса:

0)              {                  sum=value;              }          }      } } " width="640"

class Account

{

     private int sum;

     public int Sum

     {

         get {return sum;}

         set

         {

             if (value 0)

             {

                 sum=value;

             }

         }

     }

}

Автоматические свойства  Свойства управляют доступом к полям класса. Однако, если полей много, то определять каждое поле и писать для него однотипное свойство было бы утомительно. Поэтому в фреймворк .NET были добавлены автоматические свойства. Они имеют сокращенное объявление: class Person {      public string Name { get; set; }      public int Age { get; set; }                public Person(string name, int age)      {          Name = name;          Age = age;      } }

Автоматические свойства

Свойства управляют доступом к полям класса. Однако, если полей много, то определять каждое поле и писать для него однотипное свойство было бы утомительно. Поэтому в фреймворк .NET были добавлены автоматические свойства. Они имеют сокращенное объявление:

class Person

{

     public string Name { get; set; }

     public int Age { get; set; }

         

     public Person(string name, int age)

     {

         Name = name;

         Age = age;

     }

}

 В примере также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.  В чем преимущество автосвойств, если по сути они просто обращаются к автоматически создаваемой переменной, почему бы напрямую не обратиться к переменной без автосвойств? Дело в том, что в любой момент времени при необходимости мы можем развернуть автосвойство в обычное свойство, добавить в него какую-то определенную логику.  Стоит учитывать, что нельзя создать автоматическое свойство только для записи, как в случае со стандартными свойствами.  Автосвойствам можно присвоить значения по умолчанию (инициализация автосвойств):

В примере также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.

В чем преимущество автосвойств, если по сути они просто обращаются к автоматически создаваемой переменной, почему бы напрямую не обратиться к переменной без автосвойств? Дело в том, что в любой момент времени при необходимости мы можем развернуть автосвойство в обычное свойство, добавить в него какую-то определенную логику.

Стоит учитывать, что нельзя создать автоматическое свойство только для записи, как в случае со стандартными свойствами.

Автосвойствам можно присвоить значения по умолчанию (инициализация автосвойств):

class Person {      public string Name { get; set; } =

class Person

{

     public string Name { get; set; } = "Tom";

     public int Age { get; set; } = 23;

}

     

class Program

{

     static void Main(string[] args)

     {

         Person person = new Person();

         Console.WriteLine(person.Name); // Tom

         Console.WriteLine(person.Age);  // 23

         

         Console.Read();

     }

}

 Если не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.  Автосвойства также могут иметь модификаторы доступа: class Person {      public string Name { private set; get;}      public Person(string n)      {          Name = n;      } }

Если не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.

Автосвойства также могут иметь модификаторы доступа:

class Person

{

     public string Name { private set; get;}

     public Person(string n)

     {

         Name = n;

     }

}

 Можно убрать блок set и сделать автосвойство доступным только для чтения. В этом случае для хранения значения этого свойства для него неявно будет создаваться поле с модификатором readonly, поэтому следует учитывать, что подобные get-свойства можно установить либо из конструктора класса, как в примере выше, либо при инициализации свойства: class Person {      public string Name { get;} =

Можно убрать блок set и сделать автосвойство доступным только для чтения. В этом случае для хранения значения этого свойства для него неявно будет создаваться поле с модификатором readonly, поэтому следует учитывать, что подобные get-свойства можно установить либо из конструктора класса, как в примере выше, либо при инициализации свойства:

class Person

{

     public string Name { get;} = "Tom"

}

name;      // эквивалентно public string Name { get { return name; } }      } " width="640"

Сокращенная запись свойств

Как и методы, можно сокращать свойства. Например:

class Person

{

     private string name;

      public string Name = name;

     // эквивалентно public string Name { get { return name; } }

     }