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

<p id="AutBody_Root214">Роль ключевого слова this</p>

В языке 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 отображало все ваши переменные в верхней части списка. В нашем простом примере все поля являются открытыми, поэтому такое соглашение об именовании не применяется. В остальном материале книги закрытые и внутренние переменные будут именоваться с ведущим символом подчеркивания.

<p id="AutBody_Root215">Построение цепочки вызовов конструкторов с использованием this</p>
Перейти на страницу:

Похожие книги