Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

}

}

При использовании экземпляра класса, определенного с автоматическими свойствами, присваивать и получать значения можно с помощью вполне ожидаемого синтаксиса свойств:

using System;

using AutoProps;

Console.WriteLine("***** Fun with Automatic Properties *****\n");

Car c = new Car;

c.PetName = "Frank";

c.Speed = 55;

c.Color = "Red";

Console.WriteLine("Your car is named {0}? That's odd...",

c.PetName);

c.DisplayStats;

Console.ReadLine;

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

свойства и стандартные значения

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

false
для булевских и
0
для числовых данных). Но имейте в виду, что когда синтаксис автоматического свойства применяется для упаковки переменной другого класса, то скрытое поле ссылочного типа также будет установлено в стандартное значение
null
(и это может привести к проблеме, если не проявить должную осторожность).

Добавьте к текущему проекту новый файл класса по имени

Garage
(представляющий гараж), в котором используются два автоматических свойства (разумеется, реальный класс гаража может поддерживать коллекцию объектов
Car
; однако в данный момент проигнорируем такую деталь):

namespace AutoProps

{

class Garage

{

// Скрытое поддерживающее поле int установлено в О!

public int NumberOfCars { get; set; }

// Скрытое поддерживающее поле Car установлено в null!

public Car MyAuto { get; set; }

}

}

Имея стандартные значения C# для полей данных, значение

NumberOfCars
можно вывести в том виде, как есть (поскольку ему автоматически присвоено значение
0
). Но если напрямую обратиться к
MyAuto
, то во время выполнения сгенерируется исключение ссылки на
null
, потому что лежащей в основе переменной-члену типа
Car
не был присвоен новый объект.

Garage g = new Garage;

// Нормально, выводится стандартное значение 0.

Console.WriteLine("Number of Cars: {0}", g.NumberOfCars);

// Ошибка во время выполнения!

// Поддерживающее поле в данный момент равно null!

Console.WriteLine(g.MyAuto.PetName);

Console.ReadLine;

Чтобы решить проблему, можно модифицировать конструкторы класса, обеспечив безопасное создание объекта. Ниже показан пример:

class Garage

{

// Скрытое поддерживающее поле установлено в 0!

public int NumberOfCars { get; set; }

// Скрытое поддерживающее поле установлено в null!

public Car MyAuto { get; set; }

// Для переопределения стандартных значений, присвоенных скрытым

//
поддерживающим полям, должны использоваться конструкторы.

public Garage

{

MyAuto = new Car;

NumberOfCars = 1;

}

public Garage(Car car, int number)

{

MyAuto = car;

NumberOfCars = number;

}

}

После такого изменения объект

Car
теперь можно помещать в объект
Garage
:

Console.WriteLine("***** Fun with Automatic Properties *****\n");

// Создать объект автомобиля.

Car c = new Car;

c.PetName = "Frank";

c.Speed = 55;

c.Color = "Red";

c.DisplayStats;

// Поместить автомобиль в гараж.

Garage g = new Garage;

g.MyAuto = c;

// Вывести количество автомобилей в гараже

Console.WriteLine("Number of Cars in garage: {0}", g.NumberOfCars);

// Вывести название автомобиля.

Console.WriteLine("Your car is named: {0}", g.MyAuto.PetName);

Console.ReadLine;

Инициализация автоматических свойств

Наряду с тем, что предыдущий подход работает вполне нормально, в версии C# 6 появилась языковая возможность, которая содействует упрощению способа присваивания автоматическим свойствам их начальных значений. Как упоминалось ранее в главе, полю данных в классе можно напрямую присваивать начальное значение при его объявлении. Например:

class Car

{

private int numberOfDoors = 2;

}

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

Ниже приведена модифицированная версия класса

Garage
с инициализацией автоматических свойств подходящими значениями. Обратите внимание, что больше нет необходимости в добавлении к стандартному конструктору класса логики для выполнения безопасного присваивания. В коде свойству
MyAuto
напрямую присваивается новый объект
Car
.

class Garage

{

// Скрытое поддерживающее поле установлено в 1.

public int NumberOfCars { get; set; } = 1;

// Скрытое поддерживающее поле установлено в новый объект Car.

public Car MyAuto { get; set; } = new Car;

public Garage{}

public Garage(Car car, int number)

{

Поделиться с друзьями: