I'm posting this answer in response to your request that I elaborate on my comment in Joe's answer.
First point: if you need my_data_t
to be a struct for whatever reason, C# does support those. You don't have to upgrade it to a class, as Joe did, unless you want to.
public struct MyData
{
public string Description;
public uint ColourID;
public uint Quantity;
}
This is a mutable struct. Given an instance of this struct, I can modify its values if I so choose. Most people would say that mutable structs are evil. As a game developer, I would say that mutable structs are enormously important, but also dangerous.
The mutable fields and properties of any object can be initialized using the object initializer syntax, which is probably most analogous to what you're doing in C:
MyData x = { Description = "Brown Bear", ColourID = 0x88, Quantity = 10 };
Personally I think this is a bit unwieldy, especially for large structs, but it is available if you want to use it.
You can change the struct to be immutable by adding readonly
modifiers to its fields:
public struct MyData
{
public MyData(string description, uint colourID, uint quantity)
{
this.Description = description;
this.ColourID = colourID;
this.Quantity = quantity;
}
public readonly string Description;
public readonly uint ColourID;
public readonly uint Quantity;
}
Note that readonly
only prevents the object references from being changed. It does not prevent the objects themselves from being mutated, if they're mutable.
Note also that I've also added a constructor. This is because readonly
fields can only be set in a static initializer or inside of the object's constructor (barring some trickery). Here, you would initialize a new instance of MyData
as in Joe's answer:
MyData x = new MyData("Brown Bear", 0x88, 10);
Second point: constness, or the lack thereof. C# doesn't support C-style constness because C-style constness is broken. Eric Lippert, formerly a developer on the C# language team at Microsoft, elaborated on that point here.
It is far better, I think, not to worry about emulating C-style constness unless you really, really, really have a good reason to. Constness is ultimately a way to prevent your code from being tampered with by the malicious or the ignorant. The malicious are going to be able to mutate your data whether you like it or not--in C, and in C#--and we have a much better tool for protecting yourself from the ignorance of others: encapsulation!
Wrap the functionality that uses this table inside of a class, make the table a private member of that class, and then don't mutate it. If at some point you do need to expose that table to the outside world, then you can use ReadOnlyCollection
as Joe suggested:
public static readonly ReadOnlyCollection<MyData> ReferenceTable = new ReadOnlyCollection<MyData>(new []
{
new MyData(/* whatever */),
new MyData(/* whatever */),
new MyData(/* whatever */),
});
ReadOnlyCollection
is just a thin wrapper around some other collection, in this case, your data table. It can wrap any object which implements the IList<T>
interface, which includes arrays and several of the built-in collections.
One more note: in one of your comments you mentioned that one of the reasons for declaring the table const
in C is because it influences where the object is allocated in memory. This is not the case here. In the example above, RefData
will be declared on the managed heap, because it's an array, and arrays are reference types.