Обобщения. Обобщенные наборы, методы и классы.
Наборы (коллекции) хранят разные типы данных и для распознавания типов их элементов можно использовать слова: is, as, но это трудоёмко. Хотелось бы создавать такие коллекции, методы и классы, которые могли бы принимать любой тип. Для этого и служат обобщения. Обобщения – это типы, которые принимают имена других типов в качестве параметров.
В среде .NET есть обобщения для большинства классов, наборов, их эквивалентные обозначения:
ArrayList List <T>
Stack Stack <T>
HashTable Dictionary <T>
В уголковых скобах указывается замещаемый параметр, который может быть назван буквой: T – тип, K – ключ (key), V – значение (value).
Создание обобщённого набора – списка
Допустим нужно создать список целых чисел. Для этого используем класс-обобщение: List <T>. В качестве параметра будем указывать тип int. Для добавления чисел используем метод Add().
Задание №1: В проекте Планиметрия создать список целых чисел.
//В Main():
List <int> Spis_nam= new List <int> ();
Spis_nam.Add(100);
Spis_nam.Add(-75);
Spis_nam.Add(138);
//Выполнить!
Console.WriteLine("Содержимое списка: ");
foreach (int x in Spis_nam)
Console.WriteLine(x + " ");
Console.WriteLine();
//Выполнить!
Задание №2: Создать список для хранения объектов класса Point.
//В Main():
List<Point> Spis_tohk = new List<Point>();
Spis_tohk.Add(new Point(5.83, -0.17));
Spis_tohk.Add(new Point(10, 50));
//Выполнить!
Console.WriteLine("Содержимое списка точек: ");
foreach (Point Ob in Spis_tohk)
Ob.Show();
//Выполнить!
Разработка обобщённого метода
Задание №3: Создать обобщённый метод обмена значениями двух переменных любого типа в классе Point.
Такой метод лучше объявить, как статический, чтобы для его вызова не создавать объект класса Point. Его параметры должны передаваться по ссылке с помощью модификатора ref.
//В классе Point:
public static void Swap<T>(ref T a, ref T b) //T - тип
{
Console.WriteLine("Методу Swap переданы параметры типа "+typeof(T));
T x = a;
a = b;
b = x;
}
//В Main():
//1. Обмен между двумя числами типа double
double a = 8.5, b = -7.19;
Point.Swap <double> (ref a, ref b);
Console.WriteLine("Значения переменных после обмена {0:0.##}, {1:0.##}",a,b);
//Выполнить!
//2. Обмен между двумя первыми точками массива:
Point.Swap<Point>(ref mas[0], ref mas[1]);
mas[0].show();
mas[1].show();
//Выполнить!
//3. Обмен между строками:
string st1 = "Привет!", st2 = "Скоро сессия!";
Point.Swap<string>(ref st1, ref st2);
Console.WriteLine("После обмена {0}, {1}",st1,st2);
//Выполнить!
Создание обобщённого класса
Задание: В проекте Планиметрия разработать обобщённый класс Vektor. Объект_вектор определяется координатами точек его концов.
class Vektor <T>
{
T x1, x2, y1, y2; //обобщённые поля класса
//Конструктор:
public Vektor(T a, T b, T c, T d)
{
x1 = a;
y1 = b;
x2 = c;
y2 = d;
}
//Обобщённые свойства:
public T Koord_x1
{
get { return x1; }
set { x1 = value; }
}
public T Koord_y1
{
get { return y1; }
set { y1 = value; }
}
public T Koord_x2
{
get { return x2; }
set { x2 = value; }
}
public T Koord_y2
{
get { return y2; }
set { y2 = value; }
}
public void Show()
{
Console.WriteLine("Поля класса имеют тип "+typeof(T));
Console.WriteLine("x1={0:0.##}, y1 = {1:0.##}, x2={2:0.##}, y2={3:0.##}",x1,y1,x2,y2);
}
}
//В Main():
Vektor<int> V1 = new Vektor <int>(3, -8, 7, -2);
V1.Show();
//Выполнить!
V1.Koord_x1 = 100;
V1.Koord_y1 = -55;
V1.Koord_x2 = 77;
V1.Koord_y2 = -10;
V1.Show();
//Выполнить!