Каков синтаксис "<>" в C#

Я изучал основы C#, но не нашел хорошего объяснения того, что это такое:

var l = new List<string>();

Я не знаю, что делает <string> и творит чудеса ли это List. Я также видел объекты, брошенные в теги < >.

Кто-нибудь может объяснить мне это на примерах, пожалуйста?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
1 046
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Это .NET Generics. Тип внутри <> обозначает тип элемента, содержащегося в списке.

с ArrayList вам нужно будет отбрасывать элементы внутри ...

int x = (int)myArrayList[4];

с помощью List вы можете избежать этого шага, потому что компилятор уже знает тип.

int x = myList[4];

Обобщения доступны в .NET 2.0 и более поздних версиях.

Это дженерики. Вы составляете список, содержащий только строки. Вы также можете сказать

List<int>

и получите список, содержащий только целые числа.

Обобщения - это огромная тема, слишком большая, чтобы здесь можно было дать однозначный ответ.

Н.П. Я тоже удалил свое предложение. Они уходят в дыру в памяти.

Eric Z Beard 01.10.2008 02:02

Это дженерики - это форма параметризации типа. В вашем примере он заставляет 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 происходит, когда происходит упаковка и распаковка типов значений (структуры, целые числа, числа с плавающей запятой и т. д.). Нет заметного снижения производительности за приведение ссылки на объект обратно к строковой ссылке.

Robert Paulson 01.10.2008 02:57

Кроме того, это второстепенный вопрос, но Generics (или сконструированные типы) в .net не реализуются (создаются) до времени выполнения. Компилятор проверяет ваш код только во время компиляции и гарантирует, что для IList <T> .Add (T) переменная в Add(var) неявно конвертируется в T.

Robert Paulson 01.10.2008 03:08

Пример AddTwoThings неоднократно рассматривался на SO, и он недействителен.

erikkallen 19.02.2010 02:00

Это дженерики в действии. В обычном списке хранятся элементы типа 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> и создать список флагов.

Другие вопросы по теме