Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Статья из №11 журнала Алгоритм "Утреннее прикосновение шаблонов".


.Net Собеседник #63

Содержание
  1. От автора

От автора

Здравствуйте, коллеги!

Продолжаю знакомить вас со статьями будущего, 11-го номера журнала "АЛГОРИТМ".  Здесь вы сможете прочесть предварительную версию одной из статей, которые будут размещены в этом номере. Кстати, новости регулярно выкладывются в моём ЖЖ по адресу http://hdrummer.livejournal.com/

Напоминаю адрес сайта журнала - http://dotnetgrains.sql.ru/alg/alg.htm  

Не забывайте о подписке - подписной индекс для Украины 91132 в Укрпочте, для РФ - подписка через WebMoney . Подробнее на сайте журнала.

Утреннее прикосновение шаблонов

Автор: Ч.Калверт
Перевод: Чужа В.Ф.

Эта статья задумывалась как мягкое введение в тему шаблонов. И это первая статья, написанная мною на эту тему.

Обычно я пишу статьи о существующих технологиях (таких, как шаблоны) и о нарождающихся технологиях – таких, как LINQ.

Как технический писатель я всегда нацеливаюсь на максимальное количество читателей – т.е. на среднего программиста. Есть масса других прекрасных писателей и блоггеров, пишущих в расчёте на продвинутых специалистов. Моей главной целью является раскрытие общих вопросов программирования в простом и доступном стиле, позволяющем быстро разобраться с обсуждаемой темой. Иногда я стараюсь разобраться с темами, которые интересуют меня или вникнуть в продвинутую тематику, которая особенно важна. Но основные мои усилия нацелены на разбор таких тем, которые интересны большинству программистов, использующих C#.

Зачем использовать шаблоны

Шаблоны помогают разработчикам писать код, который легко использовать повторно с разными типами. Также они облегчают написание самоописывающего кода. В частности, они могут помочь вам избежать написания сбивающего с толку синтаксиса и побочных эффектов, проявляющихся при использовании приведения типов и их упаковке-распаковке. Если вы пишите контейнеры, то они пригодятся вам при написании одного класса, работающего с несколькими типами – иначе вам придётся писать реализацию такого класса для каждого используемого типа.

Ранние версии языка Basic не требовали от вас объявления типа используемой переменной. В результате такое объявление выглядит как дополнительная повинность при использовании таких языков, как Pascal или C# - ведь они являются строго типизированными. Но как только разработчик вникает в типы и начинает разбираться в них, приходит понимание того, что наличие типов важно для написания хорошего кода. Это же касается и шаблонов. Они разработаны для помощи в написании легко понятного, безопасного как в обычном, так и в повторном использовании, кода.

Конечно, C# и так является языком, соблюдающим типовую безопасность. Так к чему же ему шаблоны? Ответ прост: шаблоны помогают языку C# стать еще более типобезопасным, чем ранее. Всю эту тираду можно подытожить одним предложением: «Если тщательный контроль за типами – хорошо, то более тщательный – ещё лучше».

Проблемы, которые возникали при использовании C# до версии 2.0 можно проиллюстрировать примером, использующим стандартный класс ArrayList. Давайте рассмотрим следующий код:

   1:  ArrayList myList = new ArrayList();
   2:  myList.Add("A String"); 
// Добавим string
   3:  myList.Add(100);        
// Добавим Integer
   4:  myList.Add(1.00);       
// Добавим float

Мы поместили три разных типа в коллекцию. Конкретно – мы добавили переменные типа String, Integer и переменную типа с плавающей точкой в одну коллекцию.

C одной стороны, наличие такой возможности подразумевает высокую степень свободы работы с коллекцией. С другой – это привносит хаос в код. В приложении вам необходимо будет извлекать данные из коллекции myList в определённом порядке, согласно индексу каждой переменной определенного типа в этой коллекции. Проблемы могут начаться при случайном приведении переменной типа String, например, к типу Decimal. Однако можно конвертировать переменную типа Integer в переменную типа Decimal. Всё это вопросы удачи, которая важна в играх, но рассчитывать на которую при написании кода не стоит.

Можно и далее продолжить дискуссию, перечисляя различные проблемы, например, необходимость приведения типов при извлечении данных из колллекции:

1:  Decimal myDecimal = (Decimal)myList[2];

Но мы не станем углубляться в эту сторону. Уже и так ясно, что класс ArrayList имеет как плюсы в гибкости, так и минусы в безопасности при написании кода.

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

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

Подведем итоги. Главной целью введения шаблонов является наложение ограничений на использование типов в вашем коде. Или, выражая тоже другими словами: шаблоны предназначены для написания класса, который можно безопасно использовать с большим числом разнообразных типов без принесения в жертву безопасности использования этих типов. Остаток статьи мы посвятим демонстрации использования класса с несколькими типами, а затем написанию такого класса.

Шаблоны и безопасность типов

Теперь рассмотрим пример того, как шаблоны поддерживают безопасность типов при разработке. Вот пример, в котором показано, как с помощью шаблонов достигается та безопасность при использовании типов, которой не было ранее – при использовании коллекций в C#, таких как ArrayList:

   1:  List<string> list = new List<string>();
   2:  list.Add("Tom");  
// Работает, т.к. List типа String
   3:  list.Add(100);    
// Ошибка компиляции Invalid argument error
   4:  list.Add(1.0);    
// Ошибка компиляции Invalid argument error
   5:  String myString = list[0];

В первой строке этого кода объявляется типобезопасный шаблон класса List. Конкретно этот экземпляр работает с типом string, что указано в угловых скобках. В результате в данный контейнер можно добавить только переменные типа string. Попытка добавления переменных типа Integer или Float приведет в результате к ошибке компиляции. Генерация ошибки на стадии компиляции, а не во время выполнения и есть наибольшее преимущество шаблонов.

Функционально шаблон класса List является приблизительным эквивалентом типа ArrayList. Он призван играть ту же роль в программировании с использованием шаблонов, что и класс ArrayList при разработке стандартных контейнеров. Подобно классу ArrayList, шаблон класса List поддерживает интерфейсы ICollection, IEnumerable и IList.

Однако есть два главных отличия между этими двумя классами:

1. Шаблон класса List позволяет вам объявить тип элементов, которые вы собираетесь добавить в вашу коллекцию, класс ArrayList не имеет такого сервиса. Если вы объявляете класс List определённого типа, то переменную другого типа в коллекцию добавить нельзя. В этом примере мы указали тип string для элементов шаблона класса List.

2. Нет необходимости приведения типов при использовании элементов, размещённых в коллекции. Причина проста: гарантируется, что все элементы имеют указанный тип.

Вот пример доступа к элементу шаблона коллекции, который используется без всякого приведения типов:

   1:  String myString = list[0];

Ключевым моментом в этом параграфе является наличие ошибок компиляции в строчках 3 и 4 выше приведенного примера. Невозможно добавить в коллекцию типы, отличные от string в экземпляр шаблона класса List. Результат: вам нет необходимости беспокоиться о типе переменной, возвращаемой этим классом. Именно поэтому отпадает и необходимость приведения типов.

Рассмотрим шаблоны подробнее

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

Начнём с передачи экземпляра шаблона в метод и возврата его из метода:

   1:  public void AddSampleData(List<string> list)
   2:  {
   3:    list.Add("Tom");
   4:    list.Add("Mike");
   5:  }
   6:   
   7:  public List<string> CreateSimpleList(Boolean addSampleData)
   8:  {
   9:    List<string> list = new List<string>();
  10:    if (addSampleData)
  11:    {
  12:      AddSampleData(list);
  13:    }
  14:   
  15:    return list;
  16:  }

Эти примеры тоже достаточно просты. В метод AddSampleData мы передаём класс List типа string, где и добавляем в него некие данные. После вызова метода список будет содержать как минимум две строки. Метод CreateSimpleList является примером вызова метода AddSampleData. Отметьте создание экземпляра класса в строке 9, а также вызов метода AddSampleData в строке 12.

Далее мы увидим пример вызова метода CreateSimpleList, а затем отображение списка в соответствующем элементе управления:

   1:  List list = CreateSimpleList(true);
   2:   
   3:   foreach (String item in list)
   4:  {
   5:    listBox1.Items.Add(item);
   6:  }

Для программиста это просто рай. Вызов метода CreateSimpleList приводит к созданию инициализированного экземпляра класса List, а конструкция foreach добавляет членов коллекции к списку.

И ещё подробнее

Читайте в журнале №11 АЛГОРИТМ

Итоги

И вот мы достигли точки, начиная с которой всё становится ещё интереснее или сложнее – это уж как вам нравится. У вас могут возникнуть такие вопросы, как:



∙ Как мне создать мои собственные шаблоны классов?
∙ Могу ли я наложить ограничения на шаблон класса?
∙ Мы видели шаблоны классов и методов. Как насчет интерфейсов и делегатов?
∙ Могу ли я использовать отражение (reflection) для исследования шаблонов типов во время выполнения программы?
∙ И так далее

Ответы на эти и другие вопросы вы можете найти в этом же, 11 номере журнала «Алгоритм», в статье «И ещё раз о новшествах в C# 2.0». Если вы же проведете свои, интересные исследования шаблонов, то мы с радостью опубликуем вашу статью о них.

Удачного кодирования!

Полную версию статьи смотрите в №11 журнала АЛГОРИТМ в конце октября 2006 года.

На этом шестьдесят третий выпуск .Net Собеседника закончен.
До следующего номера.



Чужа Виталий Ф. aka hDrummer, MCAD.Net, MCDBA, MCP
hdrummer ухо gmail точка ru - жду ваши предложения и замечания.



В избранное