Вход/Регистрация
Полное руководство. С# 4.0
вернуться

Шилдт Герберт

Шрифт:

Далее обратите внимание на то, что метод CopyInsert вызывается в методе Main с помощью обычного синтаксиса и без указания аргументов типа. Дело в том, что типы аргументов различаются автоматически, а тип Т соответственно подстраи вается. Этот процесс называется выводимостью типов. Например, в первом вызове дан ного метода ArrayUtils.CopyInsert(99, 2, nums, nums2);

тип T становится типом int, поскольку числовое значение 99 и элементы массивов nums и nums2 относятся к типу int. А во втором вызове данного метода используются строковые типы, и поэтому тип Т заменяется типом string.

А теперь обратите внимание на приведенную ниже закомментированную строку кода. // ArrayUtils.CopyInsert(0.01, 2, nums, nums2);

Если удалить символы комментария в начале этой строки кода и затем попытаться перекомпилировать программу, то будет получено сообщение об ошибке. Дело в том, что первый аргумент в данном вызове метода CopyInsert относится к типу double, а третий и четвертый аргументы обозначают элементы массивов nums и nums2 типа int. Но все эти аргументы типа должны заменить один и тот же параметр типа Т, а это приведет к несоответствию типов и, как следствие, к ошибке во время компиля ции. Подобная возможность соблюдать типовую безопасность относится к одним из самых главных преимуществ обобщенных методов.

Синтаксис объявления метода CopyInsert может быть обобщен. Ниже приве дена общая форма объявления обобщенного метода. возвращаемый_тип имя_метода<список_параметров_типа>(список_параметров) { // ...

В любом случае списокпараметровтипа обозначает разделяемый запятой спи сок параметров типа. Обратите внимание на то, что в объявлении обобщенного метода список параметров типа следует после имени метода. Вызов обобщенного метода с явно указанными аргументами типа

В большинстве случаев неявной выводимости типов оказывается достаточно для вы зова обобщенного метода, тем не менее аргументы типа могут быть указаны явным об разом. Для этого достаточно указать аргументы типа после имени метода при его вы зове. В качестве примера ниже приведена строка кода, в которой метод CopyInsert вызывается с явно указываемым аргументом типа string. ArrayUtils.CopyInsert<string>("В С#", 1, strs, strs2);

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

На аргументы обобщенного метода можно наложить ограничения, указав их после списка параметров. В качестве примера ниже приведен вариант метода CopyInsert для обработки данных только ссылочных типов. public static bool CopyInsert<T>(Т e, uint idx, T[] src, T[] target) where T : class {

Если попробовать применить этот вариант в предыдущем примере программы об работки массивов, то приведенный ниже вызов метода CopyInsert не будет ском пилирован, поскольку int является типом значения, а не ссылочным типом. // Теперь неправильно, поскольку параметр Т должен быть ссылочного типа! ArrayUtils.Copylnsert(99, 2, nums, nums2); // Теперь недопустимо! Обобщенные делегаты

Как и методы, делегаты также могут быть обобщенными. Ниже приведена общая форма объявления обобщенного делегата. delegate возврашдемый_тип имя_делегата<список_параметров_типа>(список_аргументов);

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

В приведенном ниже примере программы демонстрируется применение делегата SomeOp с одним параметром типа Т. Этот делегат возвращает значение типа Т и при нимает аргумент типа Т. // Простой пример обобщенного делегата. using System; // Объявить обобщенный делегат. delegate Т SomeOp<T>(T v); class GenDelegateDemo { // Возвратить результат суммирования аргумента. static int Sum(int v) { int result = 0; for(int i=v; i>0; i--) result += i; return result; } // Возвратить строку, содержащую обратное значение аргумента. static string Reflect(string str) { string result = ""; foreach(char ch in str) result = ch + result; return result; } static void Main { // Сконструировать делегат типа int. SomeOp<int> intDel = Sum; Console.WriteLine(intDel(3)); // Сконструировать делегат типа string. SomeOp<string> strDel = Reflect; Console.WriteLine(strDel("Привет")); } }

Эта программа дает следующий результат. 6 тевирП

Рассмотрим эту программу более подробно. Прежде всего обратите внимание на следующее объявление делегата SomeOp. delegate Т SomeOp<T>(Т v);

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

Далее в классе GenDelegateDemo объявляются методы Sum и Reflect, как по казано ниже. static int Sum(int v) { static string Reflect(string str) {

  • Читать дальше
  • 1
  • ...
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: