Чтение онлайн

на главную - закладки

Жанры

C# 4.0 полное руководство - 2011

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

Шрифт:

// ...

// В некоторых случаях эти два метода не будут // отличаться своими параметрами типа, public void Set(T о) { obi = о;

}

public void Set(V о) { f ob2 = o;

}

}

class AmbiguityDemo { static void Main {

Gen<int, double> ok = new Gencint, double>;

Gen<int, int> notOK = new Gencint, int>;

ok.Set(10); // верно,

поскольку аргументы типа отличаются

notOK.Set(10); // неоднозначно, поскольку аргументы ничем не отличаются!

}

}

Рассмотрим приведенный выше код более подробно. Прежде всего обратите внимание на то, что класс Gen объявляется с двумя параметрами типа: Т и V. В классе Gen метод Set перегружается по параметрам типа Т и V, как показано ниже.

public void Set (T о) { obi = о;

}

public void Set(V o) { ob2 = o;

}

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

При таком объявлении класса Gen не соблюдается никаких требований к различению типов Т и V. Например, нет ничего принципиально неправильного в том, что объект класса Gen будет сконструирован так, как показано ниже.

Gencint, int> notOK = new Gencint, int>;

В данном случае оба типа, Т и V, заменяются типом int. В итоге оба варианта метода Set оказываются совершенно одинаковыми, что, разумеется, приводит к ошибке. Следовательно, при последующей попытке вызвать метод Set для объекта notOK в методе Main появится сообщение об ошибке вследствие неоднозначности во время компиляции.

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

Ковариантность и контравариантность в параметрах обобщенного типа

В главе 15 ковариантность и контравариантность были рассмотрены в связи с необобщенными делегатами. Эта форма ковариантности и контравариантности по-прежнему поддерживается в С#, поскольку она очень полезна. Но в версии C# 4.0 возможности ковариантности и контравариантности были расширены до параметров обобщенного типа, применяемых в обобщенных интерфейсах и делегатах.

Ковариантность и контравариантность применяется, главным образом, для рационального разрешения особых ситуаций, возникающих в связи с применением обобщенных интерфейсов и делегатов, определенных в среде .NET Framework. И поэтому некоторые интерфейсы и делегаты, определенные в библиотеке, были обновлены, чтобы использовать ковариантность и контравариантность параметров типа. Разумеется, преимуществами ковариантности и контравариантности можно также воспользоваться в интерфейсах и делегатах, создаваемых собственными силами. В этом разделе механизмы ковариантности и контравариантности параметров типа поясняются на конкретных примерах.

Применение ковариантности в обобщенном интерфейсе

Применительно к обобщенному интерфейсу ковариантность служит средством, разрешающим методу возвращать тип, производный от класса, указанного в параметре типа. В прошлом возвращаемый тип должен был в точности соответствовать параметру типа в силу строгой проверки обобщений на соответствие типов. Ковариантность смягчает это строгое правило таким образом, чтобы обеспечить типовую безопасность. Параметр ковариантного типа объявляется с помощью ключевого слова out, которое предваряет имя этого параметра.

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

//В этом обобщенном интерфейсе поддерживается ковариантность, public interface IMyCoVarGenlFCout Т> {

Т GetObject;

}

Обратите особое внимание на то, как объявляется параметр обобщенного типа Т. Его имени предшествует ключевое слово out. В данном контексте ключевое слово out обозначает, что обобщенный тип Т является ковариантным. А раз он ковариантный, то метод GetOb j ect может возвращать ссылку на обобщенный тип Т или же ссылку на любой класс, производный от типа Т.

Несмотря на свою ковариантность по отношению к обобщенному типу Т, интерфейс IMyCoVarGenlF реализуется аналогично любому другому обобщенному интерфейсу. Ниже приведен пример реализации этого интерфейса в классе MyClass.

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

T obj;

public MyClass(T v) { obj = v; } public T GetObject { return obj; }

}

Обратите внимание на то, что ключевое слово out не указывается еще раз в выражении, объявляющем реализацию данного интерфейса в классе MyClass. Это не только не нужно, но и вредно, поскольку всякая попытка еще раз указать ключевое слово out будет расцениваться компилятором как ошибка.

А теперь рассмотрим следующую простую реализацию иерархии классов.

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

Мастеровой

Дроздов Анатолий Федорович
Фантастика:
фэнтези
боевая фантастика
альтернативная история
7.40
рейтинг книги
Мастеровой

Новый Рал 9

Северный Лис
9. Рал!
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Новый Рал 9

Черный дембель. Часть 3

Федин Андрей Анатольевич
3. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 3

Семья. Измена. Развод

Высоцкая Мария Николаевна
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Семья. Измена. Развод

Матабар. II

Клеванский Кирилл Сергеевич
2. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар. II

Рейдер 2. Бродяга

Поселягин Владимир Геннадьевич
2. Рейдер
Фантастика:
фэнтези
попаданцы
7.24
рейтинг книги
Рейдер 2. Бродяга

На границе империй. Том 8

INDIGO
12. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8

Возвышение Меркурия

Кронос Александр
1. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия

Гримуар темного лорда IX

Грехов Тимофей
9. Гримуар темного лорда
Фантастика:
попаданцы
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда IX

Купец IV ранга

Вяч Павел
4. Купец
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Купец IV ранга

Зубных дел мастер

Дроздов Анатолий Федорович
1. Зубных дел мастер
Фантастика:
научная фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Зубных дел мастер

Я еще не князь. Книга XIV

Дрейк Сириус
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще не князь. Книга XIV

Неофит

Вайт Константин
1. Аннулет
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Неофит

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха