




Это .NET Generics. Тип внутри <> обозначает тип элемента, содержащегося в списке.
с ArrayList вам нужно будет отбрасывать элементы внутри ...
int x = (int)myArrayList[4];
с помощью List вы можете избежать этого шага, потому что компилятор уже знает тип.
int x = myList[4];
Обобщения доступны в .NET 2.0 и более поздних версиях.
Это дженерики. Вы составляете список, содержащий только строки. Вы также можете сказать
List<int>
и получите список, содержащий только целые числа.
Обобщения - это огромная тема, слишком большая, чтобы здесь можно было дать однозначный ответ.
Они известны как Generics (в частности, Список - это общий класс).
Чтение из MSDN
Это дженерики - это форма параметризации типа. В вашем примере он заставляет l обращаться к списку строк - список всегда будет содержать только строки: компилятор обрабатывает его (в значительной степени) так, как если бы везде, где в документах API упоминается «T», он фактически говорит «строка». Таким образом, вы можете добавлять к нему только строки, а если вы используете индексатор, вам не нужно приводить к строке и т. д.
Честно говоря, подробно рассказать о дженериках на онлайн-форуме практически невозможно. (В C# in Depth я беру почти 50 страниц, посвященных обобщениям.) Однако, вооружившись названием функции, вы будете в гораздо лучшем положении, чтобы узнать больше. MSDN «Введение в универсальные шаблоны C#», вероятно, является хорошей отправной точкой.
Задание конкретных вопросов о дженериках на SO, вероятно, даст хорошие результаты - я просто не думаю, что это действительно может быть должным образом освещено одним вопросом / ответом.
Это общий синтаксис C#.
Основная концепция заключается в том, что он позволяет вам использовать заполнитель типа и заменять реальный тип во время компиляции.
Например, старый способ:
ArrayList foos = new Arraylist();
foos.Add("Test");
работал, заставляя ArrayList хранить список System.Objects (базовый тип для всего .NET).
Итак, при добавлении или извлечении объекта из списка среда CLR должна преобразовать его в объект, в основном, что происходит на самом деле:
foos.Add("Test" as System.Object);
string s = foos[1] as String.
Это приводит к снижению производительности из-за кастинга, а также небезопасно, потому что я могу сделать это:
ArrayList listOfStrings = new ArrayList();
listOfStrings.Add(1);
listOfStrings.Add("Test");
Это будет хорошо скомпилировано, даже если я поместил целое число в listOfStrings.
Generics изменили все это, теперь, используя Generics, я могу объявить, какой тип ожидает моя коллекция:
List<int> listOfIntegers = new List<int>();
List<String> listOfStrings = new List<String>();
listOfIntegers.add(1);
// Compile time error.
listOfIntegers.add("test");
Это обеспечивает безопасность типов во время компиляции, а также позволяет избежать дорогостоящих операций приведения.
Способ использования этого довольно прост, хотя есть и некоторые сложные крайние случаи. Основная идея состоит в том, чтобы сделать ваш класс независимым от типа с помощью заполнителя типа, например, если я хочу создать общий класс «Добавить две вещи».
public class Adder<T>
{
public T AddTwoThings(T t1, T t2)
{
return t1 + t2;
}
}
Adder<String> stringAdder = new Adder<String>();
Console.Writeline(stringAdder.AddTwoThings("Test,"123"));
Adder<int> intAdder = new Adder<int>();
Console.Writeline(intAdder.AddTwoThings(2,2));
Для более подробного объяснения дженериков я не могу порекомендовать книгу CLR через C#.
fyi снижение производительности при использовании ArrayLists происходит, когда происходит упаковка и распаковка типов значений (структуры, целые числа, числа с плавающей запятой и т. д.). Нет заметного снижения производительности за приведение ссылки на объект обратно к строковой ссылке.
Кроме того, это второстепенный вопрос, но Generics (или сконструированные типы) в .net не реализуются (создаются) до времени выполнения. Компилятор проверяет ваш код только во время компиляции и гарантирует, что для IList <T> .Add (T) переменная в Add(var) неявно конвертируется в T.
Пример AddTwoThings неоднократно рассматривался на SO, и он недействителен.
Это дженерики в действии. В обычном списке хранятся элементы типа Object. Это требует приведения между типами. Это также позволит вам хранить любой элемент в одном экземпляре списка. Когда вы перебираете элементы в этом списке, вы не можете быть уверены, что все они относятся к определенному типу (по крайней мере, без преобразования каждого элемента). Например, допустим, вы создаете такой список:
List listOfStrings = new List();
Ничто не мешает сделать что-то подобное:
listOfStrings.add(6); //Not a string
Общий список позволит вам указать строго типизированный список.
List<string> listOfStrings = new List<string>();
listOfStrings.add("my name"); //OK
listofStrings.add(6); //Throws a compiler error
Здесь есть более подробные примеры Дженерики
<> предназначен для дженериков. В вашем конкретном примере это означает, что список является списком строк, а не списком целых чисел.
Обобщения используются для того, чтобы тип мог быть универсальным. Он используется ALOT в коллекциях, чтобы позволить им принимать разные типы, чтобы они могли функционировать так же, как обычный массив, и по-прежнему обнаруживать недопустимые типы, назначаемые во время компиляции. По сути, это позволяет классу сказать: «Мне нужно быть связанным с каким-то конкретным типом T, но я не хочу жестко кодировать, что это за тип, и позволять пользователю выбирать его». Например, простой массив может выглядеть примерно так:
public class MyArray<T> {
private T[] _list;
public MyArray() : this.MyArray(10);
public MyArray(int capacity)
{ _list = new T[capacity]; }
T this[int index] {
get { return _list[index]; }
set { _list[index] = value; }
}
}
Здесь у нас есть частный список типа T, доступ к которому осуществляется с помощью нашего класса как обычного массива. Нам все равно, какой это тип, для нашего кода это не имеет значения. Но любой, кто использует этот класс, может использовать его, скажем, MyArray<string> для создания списка строк, а кто-то другой может использовать его как MyArray<bool> и создать список флагов.
Н.П. Я тоже удалил свое предложение. Они уходят в дыру в памяти.