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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 210 211 212 213 214 215 216 217 218 ... 642

}

Необходимость построения полного специального обобщенного класса коллекции возникает редко; однако ключевое слово where допускается использовать также в обобщенных методах. Например, если нужно гарантировать, что метод Swap<T>() может работать только со структурами, измените его код следующим образом:

// Этот метод меняет местами любые структуры, но не классы.

static void Swap<T>(ref T a, ref T b) where T : struct

{

  ...

}

Обратите внимание, что если ограничить метод Swap<T>() в подобной манере, то менять местами объекты string (как было показано в коде примера) больше не удастся, т.к. string является ссылочным типом.

Отсутствие ограничений операций

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

// Ошибка на этапе компиляции! Невозможно

// применять операции к параметрам типа!

public class BasicMath<T>

{

  public T Add(T arg1, T arg2)

  { return arg1 + arg2; }

  public T Subtract(T arg1, T arg2)

  { return arg1 - arg2; }

  public T Multiply(T arg1, T arg2)

  { return arg1 * arg2; }

  public T Divide(T arg1, T arg2)

  { return arg1 / arg2; }

}

К сожалению, приведенный выше класс BasicMath<T> не скомпилируется. Хотя это может показаться крупным недостатком, следует вспомнить, что обобщения имеют общий характер. Конечно, числовые данные прекрасно работают с двоичными операциями С#. Тем не менее, справедливости ради, если аргумент <Т> является специальным классом или структурой, то компилятор мог бы предположить, что он поддерживает операции +, -, * и /. В идеале язык C# позволял бы ограничивать обобщенный тип поддерживаемыми операциями, как показано ниже:

// Только в целях иллюстрации!

public class BasicMath<T> where T : operator +, operator -,

  operator *, operator /

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

{

  public T Add(T arg1, T arg2)

  { return arg1 + arg2; }

  public T Subtract(T arg1, T arg2)

  { return arg1 - arg2; }

  public T Multiply(T arg1, T arg2)

  { return arg1 * arg2; }

  public T Divide(T arg1, T arg2)

  { return arg1 / arg2; }

}

Увы, ограничения операций в текущей версии C# не поддерживаются. Однако достичь желаемого результата можно (хотя и с дополнительными усилиями) путем определения интерфейса, который поддерживает такие операции (интерфейсы C# могут определять операции!), и указания ограничения интерфейса для обобщенного класса. В любом случае первоначальный обзор построения специальных обобщенных типов завершен. Во время исследования типа делегата в главе 12 мы вновь обратимся к теме обобщений.

Резюме

Глава начиналась с рассмотрения необобщенных типов коллекций в пространствах имен System.Collections и System.Collections.Specialized, включая разнообразные проблемы, которые связаны со многими необобщенными контейнерами, в том числе отсутствие безопасности в отношении типов и накладные расходы времени выполнения в форме операций упаковки и распаковки. Как упоминалось, именно по этим причинам в современных приложениях .NET будут использоваться классы обобщенных коллекций из пространств имен System.Collections.Generic и System.Collections.ObjectModel.

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

В качестве финального замечания: не забывайте, что обобщения можно обнаружить во многих местах внутри библиотек базовых классов .NET. Здесь мы сосредоточились конкретно на обобщенных коллекциях. Тем не менее, по мере проработки материала оставшихся глав (и освоения платформы) вы наверняка найдете обобщенные классы, структуры и делегаты в том или ином пространстве имен. Кроме того, будьте готовы столкнуться с обобщенными членами в необобщенном классе!

Глава 11

Расширенные средства языка C#

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

1 ... 210 211 212 213 214 215 216 217 218 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

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