Список указателей (тип указателя)?

У меня есть jus List < MyClass *> mylist ; начал изучать C #, и мне очень нравится концепция списков. Мне просто интересно, почему я не могу составить список указателей. Я пытаюсь сделать список указателей в List < int *> mylist ; мой The типа «MyClass *» не может быть использован в качестве аргумента типа , но когда я пишу:

MyClass

или даже:

List<MyClass> myList = new List<MyClass>();

MyClass myClass1 = new MyClass;
myList.Add(myClass1);

VS показывает сообщение об ошибке:

List<int> myList = new List<int>();
myList.Add(123);    

Понятия не имею почему. Есть ли какое-либо решение для этого или совершенно запрещено создавать списки указателей?

(извините за немой вопрос, я просто изучаю материал)

c#,list,pointers,types,

0

Ответов: 3


1

В C # создание списка экземпляров классов проще, чем это. Вы инициализируете список классом или значением, которое он будет хранить, а затем добавьте экземпляры или значения.

Например, список MyClass*экземпляров будет выглядеть примерно так:

int*

Или для int:

List<int*>

Вот и все. Нет необходимости в указателях для хранения экземпляров класса.

редактировать

В C # нет возможности иметь указатель на ссылочный тип или тип структуры, содержащий ссылку. Это связано с тем, что сборщик мусора может собирать ссылочный тип, даже если указатель указывает на него. Этот раздел более подробно описан в статье « Типы указателей MSDN» . Поэтому C # не допускает ничего подобного int*.

Кроме того, в той же статье вы можете найти, что единственными допустимыми типами указателей являются: sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal или bool.

Что касается вашего вопроса о MyStruct*качестве аргумента типа в MyStruct документации, то указано, что типы указателей не могут использоваться в качестве аргументов типа. Подробнее см. Главу 18.4.1.


1

Типы указателей типа Tили даже List<T>(где int*должен быть тип значения с обычным макетом, чьи экземпляры (рекурсивно) снова являются типами значений) существуют в C #, но не используются очень часто в большинстве приложений.

Однако типы указателей не могут использоваться в качестве аргументов универсального типа, поэтому « T" in int*[]не допускается MyStruct*[]. Это нормально , чтобы иметь массивы указателей, подобно typeof(List<>).MakeGenericType(typeof(int*))или objectнапример.

Чтобы ответить на ваш вопрос: Нет, нет способа использовать тип указателя для аргумента общего типа. Обратите внимание, что это не просто ограничение на C #, но и система CLR отказывается (например class, генерирует исключение).

В связи с этим типы указателей не наследуют от objectподобных «обычных» конкретных типов в системе типа C # /. NET.

В C # указатели предназначены только для значений типов. С ссылочным типом (например, с объявленным пользователем типом class) значение «значение» переменной или выражения этого типа является ссылкой (реализацией определенной ячейки памяти) на фактический экземпляр или нулевой ссылкой (не ссылается на экземпляр ). Эти ссылки несколько , как «указатели», но они не позволяют арифметику (например , добавление или вычитание ячеек памяти, или преобразования «адрес» в целое число) в том , как настоящие указатели , как int*и MyStruct*делать.


0

Как упоминалось в других ответах, вы не можете использовать тип указателя в качестве общего аргумента. В целом указатели на C # разрешены только в «небезопасных» разделах, а указатели неуправляемы - вы должны сами обрабатывать их создание и уничтожение. Я предполагаю, что указатели причин не поддерживаются в дженериках: (а) это будет путать с сбором мусора и сделать его слишком легким, чтобы стрелять в ногу, и / или (б) это просто не стоит головной боли для языковые дизайнеры, поскольку указатели должны быть очень редки в управляемом коде.

Однако в некоторых случаях это очень много, например, при взаимодействии с устаревшим кодом на C ++. Одним из полезных способов решения является класс «IntPtr». Как вы заметили, это не скомпилируется:

   MyClass* foo = ...;
   List <MyClass*> mylist = new List<MyClass*>();
   mylist.Add(foo);
   MyClass* bar = mylist[0];

Но вы должны уметь сделать (уродливое) обходное решение, наведя указатели на тип IntPtr:

   MyClass* foo = ...;
   List <IntPtr> mylist = new List<IntPtr>();
   mylist.Add((IntPtr)foo);
   MyClass* bar = (MyClass*)mylist[0];

Но опять-таки это обычно не очень удобно делать в чисто управляемом коде. Обычно я бы это сделал, только если мне нужно взаимодействовать с кодом на C ++ и иметь кучу неуправляемых структур, чтобы отслеживать.

C #, список, указатели, типы,
Похожие вопросы