Герберт Шилдт - C# 4.0: полное руководство
- Название:C# 4.0: полное руководство
- Автор:
- Жанр:
- Издательство:ООО И.Д. Вильямс
- Год:2011
- Город:Москва -- Киев
- ISBN:978-5-8459-1684-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Герберт Шилдт - C# 4.0: полное руководство краткое содержание
В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки.
Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию
C# 4.0: полное руководство - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
//на объект типа MyClass.
// Это вполне допустимо как при наличии контравариантности, так и без нее.
IMyContraVarGenIF AlphaRef = new MyClass();
// Создать ссылку из интерфейса IMyContraVarGenIF
// на объект типа MyClass.
//И это вполне допустимо как при наличии контравариантности,
// так и без нее.
IMyContraVarGenIF BetaRef = new MyClass();
// Создать ссылку из интерфейса IMyContraVarGenIF
//на объект типа MyClass.
// *** Это вполне допустимо благодаря контравариантности. ***
IMyContraVarGenIF BetaRef2 = new MyClass();
// Этот вызов допустим как при наличии контравариантности, так и без нее.
BetaRef.Show(new Beta());
// Присвоить переменную AlphaRef переменной BetaRef.
// *** Это вполне допустимо благодаря контравариантности. ***
BetaRef = AlphaRef;
BetaRef.Show(new Beta());
}
}
Выполнение этой программы дает следующий результат.
Это объект класса Beta.
Это объект класса Beta.
Контравариантный интерфейс может быть расширен аналогично описанному выше расширению ковариантного интерфейса. Для достижения контравариантного характера расширенного интерфейса в его объявлении должен быть указан такой же параметр обобщенного типа, как и у базового интерфейса, но с ключевым словом in, как показано ниже.
public interface IMyContraVarGenIF2 : IMyContraVarGenIF {
// ...
}
Следует иметь в виду, что указывать ключевое слово in
в объявлении базового интерфейса не только не нужно, но и не допустимо. Более того, сам расширенный интерфейс IMyContraVarGenIF2
не обязательно должен быть контравариантным. Иными словами, обобщенный тип Т в интерфейсе IMyContraVarGenIF2
не требуется модифицировать ключевым словом in. Разумеется, все преимущества, которые сулит контравариантность в интерфейсе IMyContraVarGen
, при этом будут утрачены в интерфейсе IMyContraVarGenIF2
.
Контравариантность оказывается пригодной только для ссылочных типов, а параметр контравариантного типа можно применять только к аргументам методов. Следовательно, ключевое слово in
нельзя указывать в параметре типа, используемом в качестве возвращаемого типа.
Как пояснялось в главе 15, ковариантность и контравариантность поддерживается в необобщенных делегатах в отношении типов, возвращаемых методами, и типов, указываемых при объявлении параметров. Начиная с версии C# 4.0, возможности ковариантности и контравариантности были распространены и на обобщенные делегаты. Подобные возможности действуют таким же образом, как было описано выше в отношении обобщенных интерфейсов.
Ниже приведен пример контравариантного делегата.
// Объявить делегат, контравариантный по отношению к обобщенному типу Т.
delegate bool SomeOp(Т obj);
Этому делегату можно присвоить метод с параметром обобщенного типа Т или же класс, производный от типа Т.
А вот пример ковариантного делегата.
// Объявить делегат, ковариантный по отношению к обобщенному типу Т.
delegate Т AnotherOp(V obj);
Этому делегату можно присвоить метод, возвращающий обобщенный тип Т, или же класс, производный от типа Т. В данном случае V оказывается просто параметром инвариантного типа.
В следующем примере программы демонстрируется применение обоих разновидностей вариантных делегатов на практике.
// Продемонстрировать конвариантность и контравариантность
// в обобщенных делегатах.
using System;
// Объявить делегат, контравариантный по отношению к обобщенному типу Т.
delegate bool SomeOp(Т obj);
// Объявить делегат, ковариантный по отношению к обобщенному типу Т.
delegate Т AnotherOp(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 и задать для него метод IsEven.
SomeOp checklt = IsEven;
// Объявить делегат SomeOp.
SomeOp checklt2;
//А теперь- присвоить делегат SomeOp делегату SomeOp.
// *** Это допустимо только благодаря контравариантности. ***
checklt2 = checklt;
// Вызвать метод через делегат.
Console.WriteLine(checklt2(objB));
// Далее, продемонстрировать контравариантность.
// Объявить сначала два делегата типа AnotherOp.
// Здесь возвращаемым типом является класс Beta,
//а параметром типа — класс Alpha.
// Обратите внимание на то, что для делегата modifylt
// задается метод Changelt.
AnotherOp modifyIt = ChangeIt;
// Здесь возвращаемым типом является класс Alpha,
// а параметром типа — тот же класс Alpha.
AnotherOp modifyIt2;
// А теперь присвоить делегат modifylt делегату modifyIt2.
// *** Это допустимо только благодаря ковариантности. ***
modifyIt2 = modifyIt;
// Вызвать метод и вывести результаты на экран.
objA = modifyIt2(objA);
Console.WriteLine(objA.Val);
}
}
Выполнение этой программы приводит к следующему результату.
False
6
Каждая операция достаточно подробно поясняется в комментариях к данной программе. Следует особо подчеркнуть, для успешной компиляции программы в объявлении обоих типов делегатов SomeOp
and AnotherOp
должны быть непременно указаны ключевые слова in
и out
соответственно. Без этих модификаторов компиляция программы будет выполнена с ошибками из-за отсутствия неявных преобразований типов в означенных строках кода.
Интервал:
Закладка: