C # Растущий список и указатели на элементы - PullRequest
0 голосов
/ 04 февраля 2011

Мне нужен растущий массив или список (встроенных достаточно).Кроме того, мне нужно иметь возможность манипулировать элементами в массиве с помощью указателей на этот конкретный элемент, например, следующий код

List<int> l1=new List<int>();

List<bool> l2=new List<bool>();

l1.Add(8);

l2.Add(true);

l1.Add(234);

l2.Add(true);

Console.WriteLine(l1[0]); //output=8

int* pointer = (int *) l1[0];

Console.WriteLine(*pointer); //Needs to output 8

Console.WriteLine(l2[0]); //output=true

bool* pointer2 = (bool *) l2[0];

Console.WriteLine(*pointer2); //Needs to output true

Заранее благодарен за любую помощь

Ответы [ 5 ]

3 голосов
/ 04 февраля 2011

Я пытаюсь использовать массив для хранения пакетных данных и передачи их потокам, эти теги должны иметь возможность изменять данные, не перегружая массив

В этом случаеЯ бы просто передал вашу List<T> в потоковую подпрограмму, а также начальный и конечный индексы, которые должен использовать поток.

Если вы всегда работаете по индексу и не выходите за пределылюбая проблема с "уничтожением массива".

2 голосов
/ 04 февраля 2011

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

Правильное решение - просто передать элемент, который вы действительно хотитепроцесс.Ссылочные типы передаются по значению, но это просто означает, что новый указатель создается для той же переменной кучи.На самом деле это не создает новое значение в куче.

Так, например:

var myList = new List<MyClass> { someInstanceofMyClass1, someInstanceofMyClass2 };
var t = new Thread(()=> SomeMethod(myList[0])); // Assuming MyClass is a reference type, the value passed here is the same instance as the one in myList
t.Start(); 
... 
1 голос
/ 04 февраля 2011

Если вы используете .NET 4, возможно, вы захотите взглянуть на классы в System.Collections.Concurrent namespace . Они предоставляют поточно-ориентированные структуры данных, которые могут помочь вам достичь вашей цели с меньшим количеством кода.

1 голос
/ 04 февраля 2011

Это уже работает так, как вы хотите для ссылочных типов.Поэтому одним из возможных решений является создание класса, который будет включать эти значения в качестве ссылочных типов.Если элементы связаны по индексу (и я подозреваю, что это так), то хорошей идеей будет сохранить один список для хранения типа, который в любом случае группирует оба значения, а не два списка.Идем с этим:

public Class MyClass
{
     public int IntValue {get;set;}
     public bool BoolValue {get;set;}
     public MyClass(int intValue, bool boolValue)
     {
          IntValue = intValue;
          boolValue = boolValue;
     }
}

List<MyClass> l1 = new List<MyClass>();
l1.Add(new MyClass(8, true));

MyClass pointer = l1[0];

Console.WriteLine(pointer.IntValue); //writes 8
Console.WriteLine(pointer.BoolValue); //writes True
0 голосов
/ 04 февраля 2011

То, что вы пытаетесь выполнить (сетевые пакеты), звучит так, как если бы вы получили System.IO.BinaryWriter вместо списка. (Вы даже можете передать NetworkStream в BinaryWriter)

Он поддерживает поиск, поэтому вы можете вернуться и переписать, и вы не можете очистить массив, так как он увеличивается автоматически.

С точки зрения производительности, я бы предположил, что BinaryWriter работает быстрее, чем List, поскольку он записывает в основной поток, а MemoryStream работает быстрее, чем List<byte>

...