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

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

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

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

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

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

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

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

Итоги урока

Свойства языка C#

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

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

Просмотр содержимого документа
«Свойства языка C#»

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

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

1

2

3

4

[модификатор_доступа] возвращаемый_тип произвольное_название

{

    // код свойства

}

Например:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class Person

{

    private string name;

 

    public string Name

    {

        get

        {

            return name;

        }

 

        set

        {

            name = value;

        }

    }

}

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

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

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

1

2

3

4

5

6

7

8

Person p = new Person();

 

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

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

p.Name = "Tom";

 

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

string personName = p.Name;

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class Person

{

    private int age;

 

    public int Age

    {

        set

        {

            if (value

            {

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

            }

            else

            {

                age = value;

            }

        }

        get { return age; }

    }

}

Если бы переменная age была бы публичной, то мы могли бы передать ей извне любое значение, в том числе отрицательное. Свойство же позволяет скрыть данные объекты и опосредовать к ним доступ.

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class Person

{

    private string name;

    // свойство только для чтения

    public string Name

    {

        get

        {

            return name;

        }

    }

 

    private int age;

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

    public int Age

    {

        set

        {

            age = value;

        }

    }

}

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

Модификаторы доступа

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class Person

{

    private string name;

 

    public string Name

    {

        get

        {

            return name;

        }

 

        private set

        {

            name = value;

        }

    }

    public Person(string name)

    {

        Name = name;

    }

}

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

1

2

3

4

5

6

Person p = new Person("Tom");

 

// Ошибка - 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

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

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

1

2

3

4

5

6

7

8

9

10

11

class Person

{

    public string Name { get; set; }

    public int Age { get; set; }

         

    public Person(string name, int age)

    {

        Name = name;

        Age = age;

    }

}

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

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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, то будут действовать значения по умолчанию.

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

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

1

2

3

4

5

6

7

8

class Person

{

    public string Name { private set; get;}

    public Person(string n)

    {

        Name = n;

    }

}

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

1

2

3

4

class Person

{

    public string Name { get;} = "Tom"

}

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

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

1

2

3

4

5

6

7

class Person

{

    private string name;

     

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

    public string Name = name;

}