КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Дополнительные ограниченияВ параметре-типе можно задать несколько дополнительных ограничений или не задавать их вообще. При задании ограничения типа-интерфейса компилятору гарантируется, что указанный аргумент-тип будет типом, реализующим этот интерфейс. А так как можно задать несколько ограничений интерфейса, в аргументе-типе должен указываться тип, реализующий все ограничения интерфейса (и все основные ограничения, если они есть). Другой тип дополнительных ограничений называют ограничением параметра-типа. Оно используется гораздо реже, чем ограничение интерфейса, и позволяет обобщенному типу или методу указать, что между указанными аргументами-типами должны быть определенные отношения. К параметру-типу может применяться несколько или ни одного ограничения типа. В следующем обобщенном методе показано использование ограничения параметра-типа.
private static List<TBase> ConvertIList<T, TBase>(IList<T> list) where T : TBase { List<TBase> baseList = new List<TBase>(list.Count); for (Int32 index = 0; index < list.Count; index++) { baseList.Add(list[index]); } return baseList; }
В методе Convert/List определены два параметра-типа, из которых параметр T ограничен параметром-типом TBase. Это значит, что какой бы аргумент-тип ни был задан для T, он должен быть совместим с аргументом-типом, заданным для TBase. В следующем методе показаны допустимые и недопустимые вызовы Convert/List.
private static void CallingConvertIList() { // Создает и инициализирует List<String> (реализующий IList<String>). IList<String> ls = new List<String>(); ls.Add("A String");
// Преобразует IList<String> в IList<0bject>. IList<Object> lo = ConvertIList<String, Object>(ls);
// Преобразует IList<String> в IList<IComparable>. IList<IComparable> lc = ConvertIList<String, IComparable>(ls);
// Преобразует IList<String> в IList<IComparable<String>. IList<IComparable<String>> lcs = ConvertIList<String, IComparable<String>>(ls);
// Преобразует IList<String> в IList<String>. IList<String> ls2 = ConvertIList<String, String>(ls);
// Преобразует IList<String> в IList<Exception>. IList<Exception> le = ConvertIList<String, Exception>(ls); // Ошибка }
В первом вызове Convert/List компилятор проверяет, чтобы String был совместим с Object. Поскольку String является производным от Object, первый вызов удовлетворяет ограничению параметра-типа. Во втором вызове Convert/List компилятор проверяет, чтобы String был совместим с IComparable. Поскольку String реализует интерфейс IComparable, второй вызов соответствует ограничению параметра-типа. В третьем вызове Convert/List компилятор проверяет, чтобы String был совместим с IComparable<String>. Так как String реализует интерфейс IComparable<String>, третий вызов соответствует ограничению параметра-типа. В четвертом вызове Convert/List компилятор знает, что String совместим сам с собой. В пятом вызове Convert/List компилятор проверяет, чтобы String был совместим с Exception. Так как String не совместим с Exception, пятый вызов не соответствует ограничению параметра-типа, и компилятор возвращает ошибку:
Error CS0309: The type 'string' must be converted to 'System.Exception' in order to use it as parameter "T" in the generic type or method SomeType.ConvertIList<T, TBase>(System.Collectons.Gene-ric.IList<T>) Ошибка CS0309: тип string должен быть преобразован в SystemException, чтобы он мог использоваться как параметр T в обобщенном коде или методе SomeType.ConvertIList<T, TBase>(System.Collectons.GenericIList<T>.
|