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

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

Книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

1 ... 144 145 146 147 148 149 150 151 152 ... 407
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

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

В качестве примера создайте новый проект консольного приложения по имени InterfaceExtensions. Цель здесь заключается в том, чтобы добавить новый метод к любому типу, который реализует интерфейс IEnumerable, что охватывает все массивы и многие классы необобщенных коллекций (вспомните из главы 10, что обобщенный интерфейс IEnumerable<T> расширяет необобщенный интерфейс IEnumerable). Добавьте к проекту следующий расширяющий класс:

using System;

namespace InterfaceExtensions

{

  static class AnnoyingExtensions

  {

    public static void PrintDataAndBeep(

      this System.Collections.IEnumerable iterator)

    {

      foreach (var item in iterator)

      {

        Console.WriteLine(item);

        Console.Beep();

      }

    }

  }

}

Поскольку метод PrintDataAndBeep() может использоваться любым классом или структурой, реализующей интерфейс IEnumerable, мы можем протестировать его с помощью такого кода:

using System;

using System.Collections.Generic;

using InterfaceExtensions;

Console.WriteLine("***** Extending Interface Compatible Types *****n");

// System.Array реализует IEnumerable!

string[] data =

  { "Wow", "this", "is", "sort", "of", "annoying",

    "but", "in", "a", "weird", "way", "fun!"};

data.PrintDataAndBeep();

Console.WriteLine();

// List<T> реализует IEnumerable!

List<int> myInts = new List<int>() {10, 15, 20};

myInts.PrintDataAndBeep();

Console.ReadLine();

На этом исследование расширяющих методов C# завершено. Помните, что данное языковое средство полезно, когда необходимо расширить функциональность типа, но вы не хотите создавать подклассы (или не можете, если тип запечатан) в целях обеспечения полиморфизма. Как вы увидите позже, расширяющие методы играют ключевую роль в API-интерфейсах LINQ. На самом деле вы узнаете, что в API-интерфейсах LINQ одним из самых часто расширяемых элементов является класс или структура, реализующая обобщенную версию интерфейса IEnumerable.

Поддержка расширяющего метода GetEnumerator() (нововведение в версии 9.0)

До выхода версии C# 9.0 для применения оператора foreach с экземплярами класса в этом классе нужно было напрямую определять метод GetEnumerator(). Начиная с версии C# 9.0, оператор foreach исследует расширяющие методы класса и в случае, если обнаруживает метод GetEnumerator(), то использует его для получения реализации IEnumerator, относящейся к данному классу. Чтобы удостовериться в сказанном, добавьте новый проект консольного приложения по имени ForEachWithExtensionMethods и поместите в него упрощенные версии классов Car и Garage из главы 8:

// Car.cs

using System;

namespace ForEachWithExtensionMethods

{

  class Car

  {

    // Свойства класса Car.

    public int CurrentSpeed {get; set;} = 0;

    public string PetName {get; set;} = "";

    // Конструкторы.

    public Car() {}

    public Car(string name, int speed)

    {

      CurrentSpeed = speed;

      PetName = name;

    }

    // Выяснить, не перегрелся ли двигатель Car.

  }

}

// Garage.cs

namespace ForEachWithExtensionMethods

{

  class Garage

  {

    public Car[] CarsInGarage { get; set; }

    // При запуске заполнить несколькими объектами Car.

    public Garage()

    {

      CarsInGarage = new Car[4];

      CarsInGarage[0] = new Car("Rusty", 30);

      CarsInGarage[1] = new Car("Clunker", 55);

      CarsInGarage[2] = new Car("Zippy", 30);

      CarsInGarage[3] = new Car("Fred", 30);

    }

  }

}

Обратите внимание, что класс Garage не реализует интерфейс IEnumerable и не имеет метода GetEnumerator(). Метод GetEnumerator() добавляется через показанный ниже класс GarageExtensions:

namespace ForEachWithExtensionMethods

{

  static class GarageExtensions

  {

    public static IEnumerator GetEnumerator(this Garage g)

        => g.CarsInGarage.GetEnumerator();

  }

}

Код для тестирования этого нового средства будет таким же, как код, который применялся для тестирования метода GetEnumerator() в главе 8. Модифицируйте файл Program.cs следующим образом:

using System;

using ForEachWithExtensionMethods;

Console.WriteLine("***** Support for Extension Method GetEnumerator *****n");

Garage carLot = new Garage();

// Проход по всем объектам Car в коллекции?

foreach (Car c in carLot)

{

    Console.WriteLine("{0} is going {1} MPH",

        c.PetName, c.CurrentSpeed);

}

Вы увидите, что код работает, успешно выводя на консоль список объектов автомобилей и скоростей их движения:

***** Support for Extension Method GetEnumerator *****

Rusty is going 30 MPH

Clunker is going 55 MPH

Zippy is going 30 MPH

Fred is going 30 MPH

На заметку! Потенциальный недостаток нового средства заключается в том, что теперь с оператором foreach могут использоваться даже те классы, которые для этого не предназначались.

Понятие анонимных типов

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

Тем не менее, возникают и другие ситуации, когда желательно определять класс просто в целях моделирования набора инкапсулированных (и каким-то образом связанных) элементов данных безо всяких ассоциированных методов, событий или другой специализированной функциональности. Кроме того, что если такой тип должен использоваться только небольшим набором методов внутри программы? Было бы довольно утомительно строить полное определение класса вроде показанного ниже, если хорошо известно, что класс будет применяться только в нескольких местах. Чтобы подчеркнуть данный момент, вот примерный план того, что может понадобиться делать, когда нужно создать "простой" тип данных, который следует обычной семантике на основе значений:

class SomeClass

{

// Определить набор закрытых переменных-членов...

// Создать свойство для каждой закрытой переменной-члена...

// Переопределить метод ToStringO для учета основных

// переменных-членов...

// Переопределить методы GetHashCode() и Equals() для работы

// с эквивалентностью на основе значений...

}

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

1 ... 144 145 146 147 148 149 150 151 152 ... 407
Перейти на страницу:
Отзывы - 0

Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.


Партнер

Новые отзывы

  1. Гость Татьяна Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
  2. Римма Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
  3. Римма Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова
Все комметарии
Новое в блоге