Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»
Книгу Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория» читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
Универсальность и специальные случаи классов
Универсальность — это механизм, воздействующий на все элементы языка. Поэтому он применим ко всем частным случаям классов C#.
Универсальные структуры
Так же, как и обычный класс, структура может иметь родовые параметры. Синтаксис объявления, ограниченная универсальность, другие детали универсальности естественным образом распространяются на структуры. Вот типичный пример:
public struct Point<T>
{
Т х, у;//координаты точки, тип которых задан параметром
// другие свойства и методы структуры
}
Универсальные интерфейсы
Интерфейсы чаще всего следует делать универсальными, предоставляя большую гибкость для позднейших этапов создания системы. Возможно, вы заметили применение в наших примерах универсальных интерфейсов библиотеки FCL — IСоmраrаЫе<T> и других. Введение универсальности, в первую очередь, сказалось на библиотеке FCL — внутренних классов, определяющих поведение системы. В частности, для большинства интерфейсов появились универсальные двойники с параметрами. Если бы в наших примерах мы использовали не универсальный интерфейс, а обычный, то потеряли бы в эффективности, поскольку сравнение объектов потребовало бы создание временных объектов типа object, выполнения операций boxing и unboxing.
Универсальные делегаты
Делегаты также могут иметь родовые параметры. Чаще встречается ситуация, когда делегат объявляется в универсальном классе и использует в своем объявлении параметры универсального класса. Давайте рассмотрим ситуацию с делегатами более подробно. Вот объявление универсального класса, не очень удачно названного Delegate, в котором объявляется функциональный тип — delegate;
class Delegate<T>
{
public delegate T Del(T a, T b);
}
Как видите, тип аргументов и возвращаемого значения в сигнатуре функционального типа определяется классом Delegate.
Добавим в класс функцию высшего порядка FunAr, одним из аргументов которой будет функция типа Del, заданного делегатом. Эта функция будет применяться к элементам массива, передаваемого также функции FunAr. Приведу описание:
public T FunAr(T[] arr, T a0, Del f)
{
T temp = a 0;
for (int i =0; i<arr.Length; i + +)
{
temp = f(temp, arr[i]);
}
return (temp);
}
Эта универсальная функция с успехом может применяться для вычисления сумм, произведения, минимума и других подобных характеристик массива.
Рассмотрим теперь клиентский класс Testing, в котором определен набор функций:
public int max2(int a, int b)
{ return (a > b)? a: b; }
public double min2(double a, double b)
{ return (a < b)? a: b; }
public string sum2(string a, string b)
{ return a + b; }
public float prod2(float a, float b)
{ return a * b; }
Хотя все функции имеют разные типы, все они соответствуют определению класса Del — имеют два аргумента одного типа и возвращают результат того же типа. Посмотрим, как они применяются в тестирующем методе класса Testing;
public void TestFun()
int[] ar1 = { 3, 5, 7, 9 }; doublet] ar2 = { 3.5, 5.7, 7.9 };
string[] агЗ = { "Мама", "мыла", "Машу", "мылом." };
float[] ar4 = { 5f, 7f, 9f, 11f };
Delegate<int> d1 = new Delegate<int>();
Delegate<int>.Del del1;
del1= this.max2;
int max = d1.FunAr(ar1, ar1[0], del1);
Console.WriteLine("max= {0}", max);
Delegate<double> d2 = new Delegate<double>();
Delegate<double>.Del del2;
del2 = this.min2;
double min = d2.FunAr(ar2, ar2[0], del2);
Console.WriteLine("min= {0}", min);
Delegate<string> d3 = new Delegate<string>();
Delegate<string>.Del del3;
del3 = this.sum2;
string sum = d3.FunAr(ar3, del3);
Console.WriteLine("concat= {0}", sum);
Delegate<float> d4 = new Delegate<float> ();
Delegate<float>.Del del4;
del4 = this.prod2;
float prod = d4.FunAr(ar4, If, del4);
Console.WriteLine("prod= {0}", prod);
}
Обратите внимание на объявление экземпляра делегата:
Delegate<int>.Del dell;
В момент объявления задается фактический тип, и сигнатура экземпляра становится конкретизированной. Теперь экземпляр можно создать и связать с конкретной функцией. В C# 2.0 это делается проще и естественнее, чем ранее, — непосредственным присваиванием:
del1= this.max2;
При выполнении этого присваивания производятся довольно сложные действия — проверяется соответствие сигнатуры функции в правой части и экземпляра делегата, в случае успеха создается новый экземпляр делегата, который и связывается с функцией.
Покажем, что и сам функциональный тип-делегат можно объявлять с родовыми параметрами. Вот пример такого объявления:
public delegate T FunTwoArg<T> (T a, T b);
Добавим в наш тестовый пример код, демонстрирующий работу с этим делегатом:
FunTwoArg<int> mydel;
myde1 = max 2;
max = mydel(17, 21);
Console.WriteLine("max= {0}", max);
Вот как выглядят результаты работы тестового примера:
Рис. 22.7. Результаты работы с универсальными делегатами
Универсальные делегаты с успехом используются при определении событий. В частности, класс EventHandler, применяемый для всех событий, не имеющих собственных аргументов, теперь дополнен универсальным аналогом, определенным следующим образом:
public void delegate EventHandler<T> (object sender, T args) where T: EventArgs
Этот делегат может применяться и для событий с собственными аргументами, поскольку вместо параметра T может быть подставлен конкретный тип — потомок класса EventArgs, дополненный нужными аргументами.
Framework.Net и универсальность
Универсальность принадлежит к основным механизмам языка. Ее введение в язык C# не могло не сказаться на всех его основных свойствах. Как уже говорилось, классы и все частные случаи стали обладать этим свойством. Введение универсальности не должно было ухудшить уже достигнутые свойства языка — статический контроль типов, динамическое связывание и полиморфизм. Не должна была пострадать и эффективность выполнения программ, использующих универсальные классы.
Решение этих задач потребовало введения универсальности не только в язык С#, но и поддержки на уровне каркаса Framework.Net и языка IL, включающем теперь параметризованные типы. Универсальный класс C# не является шаблоном, на основе которого строится конкретизированный класс, компилируемый далее в класс (тип) IL. Компилятору языка C# нет необходимости создавать классы для каждой конкретизации типов универсального класса. Вместо этого происходит компиляция универсального класса C# в параметризованный тип IL. Когда же CLR занимается исполнением управляемого кода, то вся необходимая информация о конкретных
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Наталья17 июль 12:42 Сюжет увлекательный и затейный,читается легко,но кто убийца,сразу было понятно.... Дорога к Тайнику. Часть 1 - Мария Владимировна Карташева
-
Гость Дарья16 июль 23:19 Отличная книга. Без сцен 18+, что приятно. Легкий и приятный сюжет. Благоразумная ГГ, терпеливый и сдержанный ГГ. Прочла с... Королева драконов - Анна Минаева
-
Dora16 июль 17:16 Типичная история: она — многодетная, затюканная бытом. У нее имеется богатый и красивый муж, у которого завелась любовница, а... Я беременна от вашего мужа - Ольга Ивановна Коротаева