开发者

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

开发者 https://www.devze.com 2023-02-15 22:08 出处:网络
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 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];  

T开发者_开发问答he 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.


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.


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.


If you need native interoperability, that's to say, your going to marshal these types through some mechanism or simply casting around byte arrays, then you need this unsafe/fixed stuff and it can be done like this.

unsafe struct structData 
{     
    int type;
    fixed int myArray[50]; // long is 64-bit in C# was that intentional?
    string text; // string is a managed type
}

Coming from C you should definitely not translate C code directly into the C# equivalent because that makes little sense. In C# things are managed and you typically accept the cost associated with managed code and don't think about the performance implications at that level, not at first anyway.

A good place to start would be to study the memory model of C# because it explains a lot of the subtle but important differences between value types and references types.

0

精彩评论

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

关注公众号