Create an array/List of structures when structure contains an array/List

13,322

Solution 1

public class StructData
{
    public long type;
    public long[] myArray = new long[50];
    public string text;
}

StructData[] datas = new StructData[100];

for (int i = 0; i < datas.Length; i++)
{
    datas[i] = new StructData();
}

Use classes for big objects, structs for small and possibly immutable "objects" (lets say that structs SHOULD be small AND immutable. They can be however you want) To be clear, the greatest struct I know in .NET is composed of 4 int (it's the Guid). I think it's a good benchmark for small against big structures.

Use List if you need to expand your collections, arrays if the size is fixed, List isn't much slower than arrays (they internally use an array). I don't know if anybody has ever benchmarked an array to a List. List normally uses a little more memory than an array, because it keeps a little space to enlarge the collection (and it keeps the current size of the List and a pointer to the internal array, and perhaps other data. So it's at least bigger by an int and a pointer, plus the std overhead of all the objects). You can "presize" the List by passing to the constructor the number of elements to reserve.

Solution 2

So, let me first say that you should avoid the temptation to write C code in C#. Aside from the obvious syntactical similarities, the two languages have little in common.

In C# you will rarely use structs. The semantics of a struct are different than those of a class. Here is a quick rundown on when to use a struct v when to use a class. There are more resources available, I just grabbed the first result that hit on the subject and seemed reasonable: When to use a struct

Second, yes, you should be using generic container types whenever possible. Performance will not be a problem and it will make your life a whole lot easier in the long run. your syntax for declaring the array is off (it's different than C) and should be:

long[] myArray = new long[50];

If you need the array to be pinned in memory for interop purposes you can accomplish this via the fixed keyword, but the interop layer actually does this for you anyway when you pass a managed array to a native function.

I would recommend that you spend some time learning C# from the ground up and forget about the fact that the syntax is similar to C. They are completely different languages with completely different semantics and best practices.

Share:
13,322
Nick Sinas
Author by

Nick Sinas

I have experience developing in Assembly Embedded C C++ C# Objective-C Swift Python And a tiny bit of HTML/CSS I am currently a C# and iOS developer at Metova

Updated on June 04, 2022

Comments

  • Nick Sinas
    Nick Sinas almost 2 years

    I am new to C#, normally a C programmer so I'm having trouble figuring out the best method to use. Hopefully I can get some advice to help me decide.
    I have a structure that looks like this (I did this how I would do it in C):

    struct structData
    {
        long type;
        long myArray[50];
        string text;
    }
    

    I create an array of these struct's that I can continually read/write to globally/publicly. (I will need to store the data in there so it can be accessed at a later time)

    structData arrayOfStructs[50];  
    

    The goal would be to access the data like this:

    arrayOfStructs[0].type = 123;
    arrayOfStructs[0].myArray[0] = 456;
    

    When I try to implement this in C# I get a variety of errors:
    "myArray" needs to fixed to 50, but it needs to be in unsafe area
    If I try to initialize it "... = new ..." I get an error

    First, should I be using List<> instead of arrays? Is there a performance difference?
    Second, should I create a class instead of a structure, initialize the array in a constructor, then create a list/array of the objects? How would you implement this?
    And yes I need to use longs.