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},
...
};
3 ответа
Вы можете использовать ключевое слово struct в C #. Структуры C # являются типами значений - массив структур представляет собой непрерывно хранимые структуры, идентичные стандартному массиву C ++.
Это некрасиво, но это сработает (если вы измените тип на 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
.
Вы можете сделать это, создав новую коллекцию для 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}, { ... },
};
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.
typedef
. Если это пример кода, с которым вы работаете, то это либо C (который, вероятно, легче переносить), либо очень плохой C ++ (возможно, сложнее).SomeStruct
должен бытьdouble
, а неint
.