КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Обобщенные методыПри определении обобщенного ссылочного и значимого типа или интерфейса все методы, определенные в этих типах, могут ссылаться на любой параметр-тип, заданный этим типом. Параметр-тип может использоваться как параметр метода, возвращаемое значение метода или как заданная внутри него локальная переменная. Но CLR также позволяет методу задавать собственные параметры-типы, которые могут использоваться в качестве параметров, возвращаемых значений или локальных переменных. Вот немного искусственный пример типа, определяющего параметр-тип, и метода с собственным параметром-типом:
internal sealed class GenericType<T> { private T m_value;
public GenericType(T value) { m_value = value; }
public TOutput Converter<TOutput>() { TOutput result = (TOutput)Convert.ChangeType(m_value, typeof(TOutput)); return result; } }
internal sealed class GenericType<T> { private T m_value;
public GenericType(T value) { m_value = value; }
public TOutput Converter<TOutput>() { TOutput result = (TOutput)Convert.ChangeType(m_value, typeof(TOutput)); return result; }
Здесь в классе GenericType определяется собственный параметр-тип (Т), а в методе Converter — собственный параметр-тип (TOutput). Благодаря этому можно создать класс GenericType, работающий с любым типом. Метод Converter преобразует объект, на который ссылается поле m_value, в другие типы в зависимости от аргумента-типа, переданного ему при его вызове. Наличие параметров-типов и параметров метода дает небывалую гибкость. Удачный пример обобщенного метода — метод Swap:
private static void Swap<T>(ref T o1, ref T o2) { T temp = o1; o1 = o2; o2 = temp; }
//Теперь вызывать Swap из кода можно следующим образом: private static void CallingSwap() { Int32 n1 = 1, n2 = 2; Console.WriteLine("n1={0}, n2={1}", n1, n2); Swap<Int32>(ref n1, ref n2); Console.WriteLine("n1={0}, n2={1}", n1, n2); String s1 = "Aidan", s2 = "Kristin"; Console.WriteLine("s1={0}, s2={1}", s1, s2); Swap<String>(ref s1, ref s2); Console.WriteLine("s1={0}, s2={1}", s1, s2); }
Использование обобщенных типов с методами, принимающими параметры out и ref особенно интересно тем, что переменные, передаваемые в качестве аргумента out/ref, должны быть того же типа, что и параметр метода, чтобы избежать возможных нарушений безопасности типов. В сущности, именно поэтому методы Exchange и Compare-Exchange класса Interlocked поддерживают обобщенную перегрузку:
public static class Interlocked { public static T String<T>(ref T locationl, T value) where T : class; public static T CompareExchange<T>(ref T locationl, T value, T comparand) where T : class; }
|