开发者

Convert C++ array of struct w/o tons of new calls?

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜