Вход/Регистрация
C# 4.0 полное руководство - 2011
вернуться

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

Шрифт:

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

BetaRef = AlphaRef;

BetaRef.Show(new Beta );

Прежде всего, обратите внимание на создание двух переменных ссылочного типа IMyContraVarGenlF, которым присваиваются ссылки на объекты класса MyClass, где параметры типа совпадают с аналогичными параметрами в интерфейсных ссылках. В первом случае используется параметр типа Alpha, а во втором — параметр типа Beta. Эти объявления не требуют контравариантности и допустимы в любом случае.

Далее создается переменная ссылочного типа IMyContraVarGenIF<Beta>, но на этот раз ей присваивается ссылка на объект класса MyClass<Alpha>. Эта операция вполне допустима, поскольку обобщенный тип Т объявлен как контравариантный.

Как и следовало ожидать, следующая строка, в которой вызывается метод BetaRef. Show с аргументом Beta, является вполне допустимой. Ведь Beta — это обобщенный тип Т в классе MyClass<Beta> и в то же время аргумент в методе Show .

В следующей строке переменная AlphaRef присваивается переменной BetaRef. Эта операция вполне допустима лишь в силу контравариантности. В данном случае переменная относится к типу MyClass<Beta>, а переменная AlphaRef — к типу MyClass<Alpha>. Но поскольку Alpha является базовым классом для класса Beta, то такое преобразование типов оказывается допустимым благодаря контравариантности. Для того чтобы убедиться в необходимости контравариантности в рассматриваемом здесь примере, попробуйте удалить ключевое слово in из объявления обобщенного типа Т в интерфейсе IMyContraVarGenlF, а затем попытайтесь скомпилировать приведенный выше код еще раз. В результате появятся ошибки компиляции.

Ради большей наглядности примера вся рассмотренная выше последовательность операций собрана ниже в единую программу.

// Продемонстрировать контравариантность в обобщенном интерфейсе, using System;

// Это обобщенный интерфейс, поддерживающий контравариантность. public interface IMyContraVarGenIF<in Т> { void Show(T obj);

}

// Реализовать интерфейс IMyContraVarGenlF. class MyClass<T> : IMyContraVarGenIF<T> {

public void Show(T x) { Console.WriteLine(x); }

}

// Создать простую иерархию классов, class Alpha {

public override string ToStringO { return "Это объект класса Alpha.";

}

// ...

}

class Beta : Alpha {

public override string ToStringO { return "Это объект класса Beta.";

}

// ...

}

class VarianceDemo { static void Main {

// Создать ссылку из интерфейса IMyContraVarGenIF<Alpha>

//на объект типа MyClass<Alpha>.

// Это вполне допустимо как при наличии контравариантности, так и без нее. IMyContraVarGenIF<Alpha> AlphaRef = new MyClass<Alpha>;

// Создать ссылку из интерфейса IMyContraVarGenIF<beta>

// на объект типа MyClass<Beta>.

//И это вполне допустимо как при наличии контравариантности,

// так и без нее.

IMyContraVarGenIF<Beta> BetaRef = new MyClass<Beta>;

// Создать ссылку из интерфейса IMyContraVarGenIF<beta>

//на объект типа MyClass<Alpha>.

// *** Это вполне допустимо благодаря контравариантности. *** IMyContraVarGenIF<Beta> BetaRef2 = new MyClass<Alpha>;

// Этот вызов допустим как при наличии контравариантности, так и без нее. BetaRef.Show(new Beta);

// Присвоить переменную AlphaRef переменной BetaRef.

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

BetaRef = AlphaRef;

BetaRef.Show(new Beta );

}

}

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

  • Читать дальше
  • 1
  • ...
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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