На заметку! Теперь, когда вы лучше понимаете роль конструкторов класса, полезно узнать об одном удобном сокращении. В 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
, устранив такую неоднозначность:
public void SetDriverName(string name) => this.name = name;
Если неоднозначность отсутствует, тогда применять ключевое слово this
для доступа класса к собственным полям данных или членам вовсе не обязательно. Например, если вы переименуете член данных типа string
с name
на driverName
(что также повлечет за собой модификацию операторов верхнего уровня), то потребность в использовании this
отпадет, поскольку неоднозначности с областью видимости больше нет:
class Motorcycle
{
public int driverIntensity;
public string driverName;
public void SetDriverName(string name)
{
// These two statements are functionally the same.
driverName = name;
this.driverName = name;
}
...
}
Несмотря на то что применение ключевого слова this
в неоднозначных ситуациях дает не особенно большой выигрыш, вы можете счесть его удобным при реализации членов класса, т.к. IDE-среды, подобные Visual Studio и Visual Studio Code, будут активизировать средство IntelliSense, когда присутствует this
. Это может оказаться полезным, если вы забыли имя члена класса и хотите быстро вспомнить его определение.
На заметку! Общепринятое соглашение об именовании предусматривает снабжение имен закрытых (или внутренних) переменных уровня класса префиксом в виде символа подчеркивания (скажем, _driverName
), чтобы средство IntelliSense отображало все ваши переменные в верхней части списка. В нашем простом примере все поля являются открытыми, поэтому такое соглашение об именовании не применяется. В остальном материале книги закрытые и внутренние переменные будут именоваться с ведущим символом подчеркивания.
Построение цепочки вызовов конструкторов с использованием this