Язык программирования C#9 и платформа .NET5. Страница 211
SwapFunctions.Swap<string>(ref s1, ref s2);Console.WriteLine("After swap: {0} {1}!", s1, s2);Console.ReadLine();Вот вывод:
***** Fun with Custom Generic Methods *****Before swap: 10, 90You sent the Swap() method a System.Int32After swap: 90, 10Before swap: Hello There!You sent the Swap() method a System.StringAfter swap: There Hello!Главное преимущество такого подхода в том, что придется сопровождать только одну версию
Swap<T>()Выведение параметров типа
При вызове обобщенных методов вроде
Swap<T>()System.Boolean// Компилятор выведет тип System.Boolean.bool b1 = true, b2 = false;Console.WriteLine("Before swap: {0}, {1}", b1, b2);SwapFunctions.Swap(ref b1, ref b2);Console.WriteLine("After swap: {0}, {1}", b1, b2);Несмотря на то что компилятор может определить параметр типа на основе типа данных, который применялся в объявлениях
b1b2SwapFunctions.Swap<bool>(ref b1, ref b2);Такой подход позволяет другим программистам понять, что метод на самом деле является обобщенным. Кроме того, выведение типов параметров работает только в случае, если обобщенный метод принимает, по крайней мере, один параметр. Например, пусть в классе
ProgramDisplayBaseClass<T>()static void DisplayBaseClass<T>(){ // BaseType - метод, используемый в рефлексии; // он будет описан в главе 17 Console.WriteLine("Base class of {0} is: {1}.", typeof(T), typeof(T).BaseType);}В таком случае при его вызове потребуется указать параметр типа:
...// Если метод не принимает параметров,// то должен быть указан параметр типа.DisplayBaseClass<int>();DisplayBaseClass<string>();// Ошибка на этапе компиляции! Нет параметров?// Должен быть предоставлен заполнитель!// DisplayBaseClass();Console.ReadLine();Разумеется, обобщенные методы не обязаны быть статическими, как в приведенных выше примерах. Кроме того, применимы все правила и варианты для необобщенных методов.
Создание специальных обобщенных структур и классов
Так как вы уже знаете, каким образом определять и вызывать обобщенные методы, наступило время уделить внимание конструированию обобщенной структуры (процесс построения обобщенного класса идентичен) в новом проекте консольного приложения по имени
GenericPointPointPoint<T>// Точка с координатами типа int.Point<int> p = new Point<int>(10, 10);// Точка с координатами типа double.Point<double> p2 = new Point<double>(5.4, 3.3);// Точка с координатами типа string.Point<string> p3 = new Point<string>(""",""3"");Создание точки с использованием строк поначалу может показаться несколько странным, но возьмем случай мнимых чисел, и тогда применение строк для значений
XYPoint<T>namespace GenericPoint{ // Обобщенная структура Point. public struct Point<T> { // Обобщенные данные состояния. private T _xPos; private T _yPos; // Обобщенный конструктор. public Point(T xVal, T yVal) { _xPos = xVal; _yPos = yVal; }