Создать массив / Список структур, когда структура содержит массив / Список - PullRequest
3 голосов
/ 10 марта 2011

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

struct structData
{
    long type;
    long myArray[50];
    string text;
}

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

structData arrayOfStructs[50];  

Цель состоит в том, чтобы получить доступ к таким данным:

arrayOfStructs[0].type = 123;
arrayOfStructs[0].myArray[0] = 456;

Когда я пытаюсь реализовать это в C #, я получаю множество ошибок:
«myArray» должно быть установлено на 50, но оно должно быть в небезопасной области
Если я пытаюсь инициализировать его "... = new ...", я получаю ошибку

Во-первых, я должен использовать List <> вместо массивов? Есть ли разница в производительности?
Во-вторых, я должен создать класс вместо структуры, инициализировать массив в конструкторе, а затем создать список / массив объектов? Как бы вы это реализовали?
И да, мне нужно использовать длинные.

Ответы [ 3 ]

4 голосов
/ 10 марта 2011
public class StructData
{
    public long type;
    public long[] myArray = new long[50];
    public string text;
}

StructData[] datas = new StructData[100];

for (int i = 0; i < datas.Length; i++)
{
    datas[i] = new StructData();
}

Используйте классы для больших объектов, структуры для маленьких и, возможно, неизменяемых «объектов» (допустим, что структуры ДОЛЖНЫ быть небольшими И неизменными. Они могут быть такими, как вы хотите) Чтобы было ясно, самая большая структура, которую я знаю в .NET, состоит из 4 int (это Guid). Я думаю, что это хороший ориентир для маленьких против больших структур.

Используйте List, если вам нужно расширить свои коллекции, массивы, если размер фиксирован, List не намного медленнее, чем массивы (они внутренне используют массив). Я не знаю, тестировал ли кто-нибудь когда-нибудь массив для Списка. List обычно использует немного больше памяти, чем массив, потому что он сохраняет немного места для увеличения коллекции (и сохраняет текущий размер List и указатель на внутренний массив и, возможно, другие данные. Так что он как минимум больше на int и указатель, плюс накладные расходы std для всех объектов). Вы можете «запрограммировать» список, передав конструктору количество элементов, которые нужно зарезервировать.

2 голосов
/ 10 марта 2011

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

В C # вы будете редко использовать структуры.Семантика структуры отличается от семантики класса.Вот краткое изложение того, когда использовать struct v, когда использовать класс.Доступно больше ресурсов, я просто взял первый результат, который попал в тему и показался разумным: Когда использовать структуру

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

long[] myArray = new long[50];

Если вам нужно, чтобы массив был закреплен в памяти для целей взаимодействия, вы можете сделать это с помощью ключевого слова fixed, но слой взаимодействия действительно делает это для вас в любом случае, когда вы передаете управляемый массив собственной функции.

Я бы порекомендовал вам потратить некоторое время на изучение C # с нуля и забыть о том факте, что синтаксиспохож на C. Это совершенно разные языки с совершенно другой семантикой и лучшими практиками.

0 голосов
/ 10 марта 2011

Если вам нужна встроенная совместимость, то есть вы собираетесь маршалировать эти типы с помощью какого-либо механизма или просто использовать байтовые массивы, тогда вам нужен этот небезопасный / исправленный материал, и это можно сделать следующим образом.

unsafe struct structData 
{     
    int type;
    fixed int myArray[50]; // long is 64-bit in C# was that intentional?
    string text; // string is a managed type
}

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

Хорошее место для начала - изучение памятимодель C #, потому что она объясняет множество тонких, но важных различий между типами значений и ссылочными типами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...