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

ЖАНРЫ

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

// Здесь currSpeed получит стандартное

// значение для типа int (0).

public Car(string pn) => petName = pn;

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

Конструкторы с параметрами out (нововведение в версии 7.3)

Начиная с версии C# 7.3, в конструкторах (а также в рассматриваемых позже инициализаторах полей и свойств) могут использоваться параметры

out
. В качестве простого примера добавьте в класс
Car
следующий конструктор:

public Car(string pn, int cs, out bool inDanger)

{

petName = pn;

currSpeed = cs;

if (cs > 100)

{

inDanger = true;

}

else

{

inDanger = false;

}

}

Как обычно, должны соблюдаться все правила, касающиеся параметров

out
. В приведенном примере параметру
inDanger
потребуется присвоить значение до завершения конструктора.

Еще раз о стандартном конструкторе

Как вы только что узнали, все классы снабжаются стандартным конструктором. Добавьте в свой проект новый файл по имени

Motorcycle.cs
с показанным ниже определением класса
Motorcycle
:

using System;

namespace SimpleClassExample

{

class Motorcycle

{

public void PopAWheely

{

Console.WriteLine("Yeeeeeee Haaaaaeewww!");

}

}

}

Теперь появилась возможность создания экземпляров

Motorcycle
с помощью стандартного конструктора:

Console.WriteLine("***** Fun with Class Types *****\n");

Motorcycle mc = new Motorcycle;

mc.PopAWheely;

...

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

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

Motorcycle
:

class Motorcycle

{

public int driverIntensity;

public void PopAWheely

{

for (int i = 0; i <= driverIntensity; i++)

{

Console.WriteLine("Yeeeeeee Haaaaaeewww!");

}

}

//
Вернуть стандартный конструктор, который будет.

// устанавливать все члены данных в стандартные значения

public Motorcycle {}

// Специальный конструктор.

public Motorcycle(int intensity)

{

driverIntensity = intensity;

}

}

На заметку! Теперь, когда вы лучше понимаете роль конструкторов класса, полезно узнать об одном удобном сокращении. В Visual Studio и Visual Studio Code предлагается фрагмент кода

ctor
. Если вы наберете
ctor
и нажмете клавишу <ТаЬ>, тогда IDE-среда автоматически определит специальный стандартный конструктор. Затем можно добавить нужные параметры и логику реализации. Испытайте такой прием.

Роль ключевого слова this

В языке C# имеется ключевое слово

this
, которое обеспечивает доступ к текущему экземпляру класса. Один из возможных сценариев использования
this
предусматривает устранение неоднозначности с областью видимости, которая может возникнуть, когда входной параметр имеет такое же имя, как и поле данных класса. Разумеется, вы могли бы просто придерживаться соглашения об именовании, которое не приводит к такой неоднозначности; тем не менее, чтобы проиллюстрировать такой сценарий, добавьте в класс
Motorcycle
новое поле типа
string
(под названием
name
), предназначенное для представления имени водителя. Затем добавьте метод
SetDriverName
со следующей реализацией:

class Motorcycle

{

public int driverIntensity;

// Новые члены для представления имени водителя.

public string name;

public void SetDriverName(string name) => name = name;

...

}

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

SetDriverName
и обеспечьте вывод значения поля name. Вы можете быть удивлены, обнаружив, что значением поля name является пустая строка!

// Создать объект Motorcycle с мотоциклистом по имени Tiny?

Motorcycle c = new Motorcycle(5);

c.SetDriverName("Tiny");

c.PopAWheely;

Console.WriteLine("Rider name is {0}", c.name); // Выводит пустое значение name!

Проблема в том, что реализация метода

SetDriverName
присваивает входному параметру значение его самого, т.к. компилятор предполагает, что
name
ссылается на переменную, находящуюся в области видимости метода, а не на поле
name
из области видимости класса. Для информирования компилятора о том, что необходимо установить поле данных
name
текущего объекта в значение входного параметра name, просто используйте ключевое слово
this
, устранив такую неоднозначность:

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