Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 65 66 67 68 69 70 71 72 73 ... 407
согласованный способ инициализации состояния объекта прямо во время его создания. Взгляните на следующее изменение класса Car, который теперь поддерживает в совокупности три конструктора:

class Car

{

  // 'Состояние' объекта Car.

  public string petName;

  public int currSpeed;

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

  public Car()

  {

    petName = "Chuck";

    currSpeed = 10;

  }

  // Здесь currSpeed получает стандартное значение для типа int (0).

  public Car(string pn)

  {

    petName = pn;

  }

  // Позволяет вызывающему коду установить полное состояние объекта Car.

  public Car(string pn, int cs)

  {

    petName = pn;

    currSpeed = cs;

  }

...

}

Имейте в виду, что один конструктор отличается от другого (с точки зрения компилятора С#) числом и/или типами аргументов. Вспомните из главы 4, что определение метода с тем же самым именем, но разным количеством или типами аргументов, называется перегрузкой метода. Таким образом, конструктор класса Car перегружен, чтобы предложить несколько способов создания объекта во время объявления. В любом случае теперь есть возможность создавать объекты Car, используя любой из его открытых конструкторов. Вот пример:

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

// Создать объект Car по имени Chuck со скоростью 10 миль в час.

Car chuck = new Car();

chuck.PrintState();

// Создать объект Car по имени Mary со скоростью 0 миль в час.

Car mary = new Car("Mary");

mary.PrintState();

// Создать объект Car по имени Daisy со скоростью 75 миль в час.

Car daisy = new Car("Daisy", 75);

daisy.PrintState();

...

Конструкторы в виде членов, сжатых до выражений (нововведение в версии 7.0)

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

// Здесь 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;

  //

1 ... 65 66 67 68 69 70 71 72 73 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий