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), 
   ... 
};

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

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

Дело в том, что я хочу избежать вызова 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}, ... };

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

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}, 
   ... 
   };
2
Razzupaltuff 1 Сен 2010 в 17:30
1
Образец кода C ++ на самом деле выполнен в стиле C. В C ++ нет необходимости в typedef. Если это пример кода, с которым вы работаете, то это либо C (который, вероятно, легче переносить), либо очень плохой C ++ (возможно, сложнее).
 – 
David Thornley
1 Сен 2010 в 17:56
Третий параметр конструктора SomeStruct должен быть double, а не int.
 – 
Ben Voigt
1 Сен 2010 в 18:07
Дэвид, я знаю, что typedef мне не нужен, но так я считаю его более читаемым. Бен, вы правы, но это всего лишь пример, который я написал за минуту без тщательной проверки, и он достаточно хорош, потому что проясняет принцип. Я хотел бы попросить вас обоих не публиковать в будущем нерелевантные ответы, которые на самом деле не имеют ничего общего с вопросом. Спасибо.
 – 
Razzupaltuff
2 Сен 2010 в 03:51

3 ответа

Лучший ответ

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

2
Puppy 1 Сен 2010 в 17:38
Я пробовал это, но все еще не смог инициализировать массив значениями структуры, например, SomeStruct [] a = новый SomeStruct [1000] {{0,0,0.0}, {1,1,1.0} ...};
 – 
Razzupaltuff
2 Сен 2010 в 03:57
- ты читал мое решение? Это единственный способ избежать новых вызовов в синтаксисе инициализации.
 – 
Mark H
2 Сен 2010 в 04:49
Да, и спасибо за ваше предложение. Я скорее искал, чтобы избежать необходимости выделять каждую структуру отдельно.
 – 
Razzupaltuff
4 Сен 2010 в 17:17

Это некрасиво, но это сработает (если вы измените тип на 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;

Изменить:

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

0
leppie 1 Сен 2010 в 17:42
Это присвоение, а не инициализация. Это также не работает для неизменяемых типов значений, которые рекомендуются.
 – 
Ben Voigt
1 Сен 2010 в 18:06

Вы можете сделать это, создав новую коллекцию для 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
Mark H 1 Сен 2010 в 17:54