Преобразовать массив C ++ из структуры без множества новых вызовов? - PullRequest
2 голосов
/ 01 сентября 2010

C ++

typedef struct someStruct {
   int val1, val2;
   double val3;
} someStruct;

someStruct a [1000] = { {0, 0, 0.0}, {1, 1, 1.0}, ... };

Единственный способ инициализации такой таблицы в C #, о котором я знаю, это написать что-то вроде

class SomeStruct 
{
   int val1, val2;
   double val3;

   public SomeStruct (int val1, int val2, double val3)
   {
      this.val1 = val1;
      this.val2 = val2;
      this.val3 = val3;
   }
}

SomeStruct[] a = new SomeStruct [1000] 
{ 
   new SomeStruct (0, 0, 0.0), 
   new SomeStruct (1, 1, 1.0), 
   ... 
};

Есть ли способ иметь (ссылаться на) массив значений типа класса SomeClass вместо указателей на них?

Edit:

Дело в том, что я хочу избежать вызова new для каждой структуры в массиве. Поэтому я хочу, чтобы массив содержал 1000 структур, а не 1000 указателей на (1000) структур. Причина, по которой я спрашиваю, состоит в том, что способ, которым C # обрабатывает это, кажется мне безумно неэффективным, включая большие затраты памяти и управление памятью (например, C ++).

Я пробовал что-то вроде

struct SomeStruct {
   int a, b;
   double c;
   }

SomeStruct[] a = new SomeStruct [1000] { {0,0,0.0}, {1,1,1.0}, ... };

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

struct SomeStruct {
   int a, b;
   double c;
   SomeStruct (int a, int b, double c) {
      this.a = a; this.b = b; this.c = c;
      }
   }

SomeStruct[] a = new SomeStruct [1000] { 
   new SomeStruct {0,0,0.0}, 
   new SomeStruct {1,1,1.0}, 
   ... 
   };

Ответы [ 3 ]

2 голосов
/ 01 сентября 2010

Вы можете использовать ключевое слово struct в C #. Структуры C # являются типами значений. Массив структур представляет собой непрерывно хранимые структуры, идентичные стандартному массиву C ++.

0 голосов
/ 01 сентября 2010

Вы можете сделать это, создав новую коллекцию для SomeStruct (производную от IEnumerable<>). Каждый элемент, который вы используете в синтаксисе инициализации, преобразуется в вызов .Add(...), поэтому при условии, что в вашем классе коллекции есть метод Add ( для этого не нужно наследовать от любого другого интерфейса), с соответствующими аргументами вы можете использовать тот же синтаксис C ++.

например.

public class SomeStructCollection : IEnumerable<SomeStruct> {
    private readonly SomeStruct[] someStructs = new SomeStruct[1000];
    private int currentIndex;

    public void Add(int val1, int val2, double val3) {
        someStructs[currentIndex++] = new SomeStruct(val1, val2, val3);
    }

    public SomeStruct this[int index] {
        get { return someStructs[index];
    }

    //Implement IEnumerable<> interface.
}

Затем вызывающий код может переносить значения в некоторые блоки

SomeStructCollection coll = new SomeStructCollection {
    {0, 0, 0.0}, {1, 1, 1.0}, { ... },
};
0 голосов
/ 01 сентября 2010

Это ужасно, но это сработает (если вы измените тип на struct вместо class)

SomeStruct[] a = new SomeStruct [1000];
a[0].val1 = 0;
a[0].val2 = 1;
a[0].val3 = 2.0;
...
a[999].val1 = 0;
a[999].val2 = 1;
a[999].val3 = 2.0;

Edit:

Если это глобальное поле, объявите a как static readonly.

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