Kniga-Online.club
» » » » Герберт Шилдт - C# 4.0: полное руководство

Герберт Шилдт - C# 4.0: полное руководство

Читать бесплатно Герберт Шилдт - C# 4.0: полное руководство. Жанр: Программирование издательство -, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Ниже приведен пример контравариантного делегата.

// Объявить делегат, контравариантный по отношению к обобщенному типу Т.

delegate bool SomeOp<in Т>(Т obj);

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

А вот пример ковариантного делегата.

// Объявить делегат, ковариантный по отношению к обобщенному типу Т.

delegate Т AnotherOp<out Т, V>(V obj);

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

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

// Продемонстрировать конвариантность и контравариантность

// в обобщенных делегатах.

using System;

// Объявить делегат, контравариантный по отношению к обобщенному типу Т.

delegate bool SomeOp<in Т>(Т obj);

// Объявить делегат, ковариантный по отношению к обобщенному типу Т.

delegate Т AnotherOp<out Т, V>(V obj);

class Alpha {

  public int Val { get; set; }

  public Alpha(int v) { Val = v; }

}

class Beta : Alpha {

  public Beta(int v) : base(v) { }

}

class GenDelegateVarianceDemo {

  // Возвратить логическое значение true, если значение

  // переменной obj.Val окажется четным,

  static bool IsEven(Alpha obj) {

    if ((obj.Val % 2) == 0) return true;

    return false;

  }

  static Beta ChangeIt(Alpha obj) {

    return new Beta(obj.Val + 2);

  }

  static void Main() {

    Alpha objA = new Alpha(4);

    Beta objB = new Beta(9);

    // Продемонстрировать сначала контравариантность.

    // Объявить делегат SomeOp<Alpha> и задать для него метод IsEven.

    SomeOp<Alpha> checklt = IsEven;

    // Объявить делегат SomeOp<Beta>.

    SomeOp<Beta> checklt2;

    //А теперь- присвоить делегат SomeOp<Alpha> делегату SomeOp<Beta>.

    // *** Это допустимо только благодаря контравариантности. ***

    checklt2 = checklt;

    // Вызвать метод через делегат.

    Console.WriteLine(checklt2(objB));

    // Далее, продемонстрировать контравариантность.

    // Объявить сначала два делегата типа AnotherOp.

    // Здесь возвращаемым типом является класс Beta,

    //а параметром типа — класс Alpha.

    // Обратите внимание на то, что для делегата modifylt

    // задается метод Changelt.

    AnotherOp<Beta, Alpha> modifyIt = ChangeIt;

    // Здесь возвращаемым типом является класс Alpha,

    // а параметром типа — тот же класс Alpha.

    AnotherOp<Alpha, Alpha> modifyIt2;

    // А теперь присвоить делегат modifylt делегату modifyIt2.

    // *** Это допустимо только благодаря ковариантности. ***

    modifyIt2 = modifyIt;

    // Вызвать метод и вывести результаты на экран.

    objA = modifyIt2(objA);

    Console.WriteLine(objA.Val);

  }

}

Выполнение этой программы приводит к следующему результату.

False

6

Каждая операция достаточно подробно поясняется в комментариях к данной программе. Следует особо подчеркнуть, для успешной компиляции программы в объявлении обоих типов делегатов SomeOp and AnotherOp должны быть непременно указаны ключевые слова in и out соответственно. Без этих модификаторов компиляция программы будет выполнена с ошибками из-за отсутствия неявных преобразований типов в означенных строках кода.

Создание экземпляров объектов обобщенных типов

Когда приходится иметь дело с обобщениями, то нередко возникает вопрос: не приведет ли применение обобщенного класса к неоправданному раздуванию кода? Ответ на этот вопрос прост: не приведет. Дело в том, что в C# обобщения реализованы весьма эффективным образом: новые объекты конструируемого типа создаются лишь по мере надобности. Этот процесс описывается ниже.

Когда обобщенный класс компилируется в псевдокод MSIL, он сохраняет все свои параметры типа в их обобщенной форме. А когда конкретный экземпляр класса потребуется во время выполнения программы, то JIT-компилятор сконструирует конкретный вариант этого класса в исполняемом коде, в котором параметры типа заменяются аргументами типа. В каждом экземпляре с теми же самыми аргументами типа будет использоваться один и тот же вариант данного класса в исполняемом коде.

Так, если имеется некоторый обобщенный класс Gen<T>, то во всех объектах типа Gen<T> будет использоваться один и тот же исполняемый код данного класса. Следовательно, раздувание кода исключается благодаря тому, что в программе создаются только те варианты класса, которые действительно требуются. Когда же возникает потребность сконструировать объект другого типа, то компилируется новый вариант класса в исполняемом коде.

Как правило, новый исполняемый вариант обобщенного класса создается для каждого объекта конструируемого типа, в котором аргумент имеет тип значения, например int или double. Следовательно, в каждом объекте типа Gen<int> будет использоваться один исполняемый вариант класса Gen, а в каждом объекте типа Gen<double> — другой вариант класса Gen, причем каждый вариант приспосабливается к конкретному типу значения. Но во всех случаях, когда аргумент оказывается ссылочного типа, используется только один вариант обобщенного класса, поскольку все ссылки имеют одинаковую длину (в байтах). Такая оптимизация также исключает раздувание кода.

Некоторые ограничения, присущие обобщениям

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

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

•    К обобщенному методу нельзя применять модификатор extern.

•    Типы указателей нельзя использовать в аргументах типа.

•    Если обобщенный класс содержит поле типа static, то в объекте каждого конструируемого типа должна быть своя копия этого поля. Это означает, что во всех экземплярах объектов одного конструируемого типа совместно используется одно и то же поле типа static. Но в экземплярах объектов другого конструируемого типа совместно используется другая копия этого поля. Следовательно, поле типа static не может совместно использоваться объектами всех конструируемых типов.

Заключительные соображения относительно обобщений

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

ГЛАВА 19 LINQ 

 Без сомнения, LINQ относится к одним из самых интересных средств языка С#. Эти средства были внедрены в версии C# 3.0 и явились едва ли не самым главным его дополнением, которое состояло не только во внесении совершенно нового элемента в синтаксис С#, добавлении нескольких ключевых слов и предоставлении больших возможностей, но и в значительном расширении рамок данного языка программирования и круга задач, которые он позволяет решать. Проще говоря, внедрение LINQ стало поворотным моментом в истории развития С#.

Перейти на страницу:

Герберт Шилдт читать все книги автора по порядку

Герберт Шилдт - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


C# 4.0: полное руководство отзывы

Отзывы читателей о книге C# 4.0: полное руководство, автор: Герберт Шилдт. Читайте комментарии и мнения людей о произведении.


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

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

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


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*