C# Обобщения
ОбобщенияПозволяют отложить указание типа данных программных элементов в классе или методе до тех пор, пока он фактически не будет использован в программе. Иными словами, обобщения позволяют писать класс или метод, который может работать с любым типом данных.
Вы можете писать спецификации для классов или методов, используя параметры-заместители для типов данных. Когда компилятор встречает конструктор класса или вызов метода, он генерирует код для обработки указанного типа данных. Следующий простой пример поможет вам понять эту концепцию:
Пример
using System.Collections.Generic;
namespace GenericApplication
{
public class MyGenericArray<T>
{
private T[] array;
public MyGenericArray(int size)
{
array = new T[size + 1];
}
public T getItem(int index)
{
return array[index];
}
public void setItem(int index, T value)
{
array[index] = value;
}
}
class Tester
{
static void Main(string[] args)
{
// Объявить целочисленный массив
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
// Установить значение
for (int c = 0; c < 5; c++)
{
intArray.setItem(c, c*5);
}
// Получить значение
for (int c = 0; c < 5; c++)
{
Console.Write(intArray.getItem(c) + " ");
}
Console.WriteLine();
// Объявить массив символов
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
// Установить значение
for (int c = 0; c < 5; c++)
{
charArray.setItem(c, (char)(c+97));
}
// Получить значение
for (int c = 0; c < 5; c++)
{
Console.Write(charArray.getItem(c) + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
0 5 10 15 20 a b c d e
Возможности обобщений
Использование обобщений — это приём для улучшения функциональности программы, а именно в следующих аспектах:
- Это помогает максимально повторно использовать код, обеспечивать безопасность типов и повышать производительность.
- Вы можете создавать обобщенные классы коллекций. Библиотека классов .NET Framework в пространстве именSystem.Collections.Genericсодержит некоторые новые обобщенные классы коллекций. Вы можете использовать эти обобщенные классы коллекций для заменыSystem.CollectionsКлассы коллекций в.
- Вы можете создавать собственные обобщенные интерфейсы, обобщенные классы, обобщенные методы, обобщенные события и обобщенные делегаты.
- Вы можете ограничивать обобщенные классы для доступа к методам конкретных типов данных.
- Информацию о типах, используемых в обобщенных типах данных, можно получить во время выполнения с помощью отражения.
Обобщенные методы
В приведенном выше примере мы использовали обобщенные классы. Мы можем объявлять обобщенные методы с помощью параметров типа. Следующая программа иллюстрирует эту концепцию:
Пример
using System.Collections.Generic;
namespace GenericMethodAppl
{
class Program
{
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
static void Main(string[] args)
{
int a, b;
char c, d;
a = 10;
b = 20;
c = 'I';
d = 'V';
// Вывести значения до обмена
Console.WriteLine("Значения Int до вызова swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Значения Char до вызова swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
// вызов swap
Swap<int>(ref a, ref b);
Swap<char>(ref c, ref d);
// Вывести значения после обмена
Console.WriteLine("Значения Int после вызова swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Значения Char после вызова swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
Console.ReadKey();
}
}
}
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
Int values before calling swap: a = 10, b = 20 Char values before calling swap: c = I, d = V Int values after calling swap: a = 20, b = 10 Char values after calling swap: c = V, d = I
Обобщённые делегаты
Вы можете определять обобщённые делегаты, используя параметры типа. Например:
delegate T NumberChanger<T>(T n);
В следующем примере демонстрируется использование делегатов:
Пример
using System.Collections.Generic;
delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl
{
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
// Создать экземпляр делегата
NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
// Использовать объект делегата для вызова метода
nc1(25);
Console.WriteLine("Значение Num: {0}", getNum());
nc2(5);
Console.WriteLine("Значение Num: {0}", getNum());
Console.ReadKey();
}
}
}
Когда приведенный выше код скомпилирован и выполнен, он выдает следующие результаты:
Value of Num: 35 Value of Num: 175Другие расширения