2

I need a small datatype that has exactly X bytes.

To archive this I have basically two ways:

  • I could define a byte[]-array with a capacity of X
  • I could combine some build-in numeric types to archive the number of bytes I need, f. e. for X = 12:
    • I could use 3 integers
    • I could use 1 long and one short
    • I could use 12 byte fields
    • I could ...

I have seen that in a lot of structs f. e. Guid or MongoDb's ObjectId concrete fields are used, even if they are more or less just a plain byte array.

public struct XY
{
    private readonly int _a;
    private readonly int _b;
    private readonly int _c;
}

vs.

public struct XY
{
    private readonly byte[] bytes = new byte[12]; // probably set via ctor
}

Does this provide any significant benefits (apart from usability)?

Or to put it in another way: Is using a byte array within a struct a bad idea?

BudBrot
  • 1,341
  • 2
  • 24
  • 44
  • probably related: https://stackoverflow.com/questions/4853213/are-structs-always-stack-allocated-or-sometimes-heap-allocated – rene Apr 20 '23 at 09:43
  • 1
    Note that since array is a reference type the second approach will lead to all the corresponding consequences like increased memory consumption, heap allocation, etc. – Guru Stron Apr 20 '23 at 09:48

2 Answers2

6

The reason plain fields are most commonly used in structs is that they will be stored as part of the struct. So if I have an Guid[], then all the data will be stored in a single contiguous memory block. And this have benefits with regards to data locality and memory usage.

If you store an array your struct will only contain a single reference, while the actual data will be stored elsewhere, and accessing the data needs an indirection. That does not mean you should never store arrays as part of a struct, but it is most beneficial if you need data that is varying in size, or some other special need.

For small fixed size data, using individual fields is probably preferable. If you want to treat the fields as a sequence of values you can always implement IEnumerable/IReadOnlyCollection/IReadOnlyList.

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • 3
    Even if using individual fields is probably preferable, we can provide a *property* (indexer) to *view* these fields as if they are in array; +1 – Dmitry Bychenko Apr 20 '23 at 09:49
2

It depends on the data you want to store.

If you can devide the data into semantically-meaningful pieces that it would make sense to process separately (up to your use case), do so.

If the data is a buffer, blob or some binary chunk, it's better to use a byte array.

In other words, it's best to adhere to the semantic representation of your data when defining a data structure.

mimak
  • 211
  • 2
  • 9