Что означает <T> в С#
Я новичок в С# и прямо погружаюсь в модификацию некоторого кода для проекта, который я получил. Тем не менее, я продолжаю видеть код следующим образом:
class SampleCollection<T>
и я не могу понять, что
<T>
означает и то, что он называется.
Если кто-то захочет помочь мне просто назвать, что называется этим понятием, я могу найти его в Интернете. Тем не менее, я до сих пор не знаю.
Ответы
Ответ 1
Это параметр общего типа.
Параметр универсального типа позволяет вам указать произвольный тип T для метода во время компиляции без указания конкретного типа в объявлении метода или класса.
Например:
public T[] Reverse<T>(T[] array)
{
var result = new T[array.Length];
int j=0;
for(int i=array.Length - 1; i>= 0; i--)
{
result[j] = array[i];
j++;
}
return result;
}
инвертирует элементы в массиве. Ключевым моментом здесь является то, что элементы массива могут быть любого типа, и функция все равно будет работать. Вы указываете тип в вызове метода; безопасность типов все еще гарантирована.
Итак, чтобы обратить массив строк:
string[] array = new string[] { "1", "2", "3", "4", "5" };
var result = reverse(array);
Создает массив строк в result
{ "5", "4", "3", "2", "1" }
Это имеет тот же эффект, как если бы вы вызывали обычный (не универсальный) метод, который выглядит следующим образом:
public string[] Reverse(string[] array)
{
var result = new string[array.Length];
int j=0;
for(int i=array.Length - 1; i >= 0; i--)
{
result[j] = array[i];
j++;
}
return result;
}
Компилятор видит, что array
содержит строки, поэтому он возвращает массив строк. string
типа заменяется на параметр типа T
Параметры универсального типа также можно использовать для создания универсальных классов. В приведенном вами примере SampleCollection<T>
T
является заполнителем для произвольного типа; это означает, что SampleCollection
может представлять коллекцию объектов, тип которых вы указываете при создании коллекции.
Так:
var collection = new SampleCollection<string>();
создает коллекцию, которая может содержать строки. Reverse
выше метод Reverse
в несколько ином виде может использоваться для реверсирования элементов коллекции.
Ответ 2
Это параметр общего типа, см. Документацию по универсальным типам.
T
не является зарезервированным ключевым словом. T
или любое другое имя означает параметр типа. Проверьте следующий метод (просто как простой пример).
T GetDefault<T>()
{
return default(T);
}
Обратите внимание, что тип возвращаемого значения - T
С помощью этого метода вы можете получить значение по умолчанию любого типа, вызвав метод как:
GetDefault<int>(); // 0
GetDefault<string>(); // null
GetDefault<DateTime>(); // 01/01/0001 00:00:00
GetDefault<TimeSpan>(); // 00:00:00
.NET использует дженерики в коллекциях... пример:
List<int> integerList = new List<int>();
Таким образом, у вас будет список, который принимает только целые числа, потому что экземпляр класса создается с типом T
, в данном случае int
, а метод добавления элементов записывается так:
public class List<T> : ...
{
public void Add(T item);
}
Еще немного информации о дженериках.
Вы можете ограничить область действия типа T
В следующем примере вы можете вызывать метод только с типами, которые являются классами:
void Foo<T>(T item) where T: class
{
}
В следующем примере вы можете вызывать метод только с типами Circle
или наследовать от него.
void Foo<T>(T item) where T: Circle
{
}
И есть new()
который говорит, что вы можете создать экземпляр T
если у него есть конструктор без параметров. В следующем примере T
будет рассматриваться как Circle
, вы получите intellisense...
void Foo<T>(T item) where T: Circle, new()
{
T newCircle = new T();
}
Поскольку T
является параметром типа, вы можете получить объект Type
из него. С Type
вы можете использовать отражение...
void Foo<T>(T item) where T: class
{
Type type = typeof(T);
}
В качестве более сложного примера проверьте подпись ToDictionary
или любого другого метода Linq.
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
Нет T
, но есть TKey
и TSource
. Рекомендуется всегда указывать параметры типа с префиксом T
как показано выше.
Вы можете назвать TSomethingFoo
если хотите.
Ответ 3
Эта функция называется дженериками. http://msdn.microsoft.com/en-us/library/512aeb7t(v=vs.100).aspx
Примером этого является создание коллекции элементов определенного типа.
class MyArray<T>
{
T[] array = new T[10];
public T GetItem(int index)
{
return array[index];
}
}
В вашем коде вы можете сделать что-то вроде этого:
MyArray<int> = new MyArray<int>();
В этом случае T[] array
будет работать как int[] array
, а public T GetItem
будет работать как public int GetItem
.