C++
typedef struct someStruct {
int val1, val2;
double val3;
} someStruct;
someStruct a [开发者_开发百科1000] = { {0, 0, 0.0}, {1, 1, 1.0}, ... };
The only way to initialize such a table in C# I know of is to write something like
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),
...
};
Is there a way to have a be a (reference to) an array of values of type class SomeClass instead to pointers to those?
Edit:
The point is that I want to avoid having to call new for each struct in the array. So what I want is an array containg 1000 structs and not 1000 pointers to (1000) structs. The reason I am asking is that the way C# handles this appears insanely inefficent to me, involving a lot of memory and memory management overhead (over e.g. C++).
I had tried something like
struct SomeStruct {
int a, b;
double c;
}
SomeStruct[] a = new SomeStruct [1000] { {0,0,0.0}, {1,1,1.0}, ... };
But that wasn't possible. So though I know that structs are value types, I concluded that this is only true when passing them as parameters to function, and I had to use new, like this (using structs here):
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},
...
};
You can use the struct keyword in C#. C# structs are value types- an array of structs is contiguously stored structs, identical to a C++ standard array.
It's ugly, but this will work (if you change the type to struct
instead of 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:
If this is a global field, declare a
as static readonly
.
You can do this by creating a new collection for SomeStruct (derived from IEnumerable<>
) Each item you use in the initialization syntax gets converted to a call to .Add(...)
, so provided your collection class has a method called Add (doesn't need to inherit from any other interface for this), with matching arguments, you can use the same C++ syntax.
eg.
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.
}
Calling code can then wrap values in some blocks
SomeStructCollection coll = new SomeStructCollection {
{0, 0, 0.0}, {1, 1, 1.0}, { ... },
};
精彩评论