ジョーの回答で私のコメントについて詳しく説明するというあなたの要求に応えて、この回答を投稿しています。
my_data_t
最初のポイント:何らかの理由で構造体にする必要がある場合、C# はそれらをサポートします。必要でない限り、Joe が行ったようにクラスにアップグレードする必要はありません。
public struct MyData
{
public string Description;
public uint ColourID;
public uint Quantity;
}
これは変更可能な構造体です。この構造体のインスタンスが与えられた場合、必要に応じてその値を変更できます。ほとんどの人は、変更可能な構造体は悪だと言うでしょう。ゲーム開発者として、可変構造体は非常に重要であると同時に危険でもあると言えます。
任意のオブジェクトの変更可能なフィールドとプロパティは、オブジェクト初期化構文を使用して初期化できます。これはおそらく、C で行っていることと最も類似しています。
MyData x = { Description = "Brown Bear", ColourID = 0x88, Quantity = 10 };
個人的には、特に大きな構造体の場合、これは少し扱いにくいと思いますが、使用したい場合は利用できます。
readonly
フィールドに修飾子を追加することで、構造体を不変に変更できます。
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;
}
readonly
オブジェクト参照が変更されないようにするだけであることに注意してください。オブジェクトが変更可能であれば、オブジェクト自体が変更されるのを防ぐことはできません。
また、コンストラクターも追加したことに注意してください。これは、readonly
フィールドは静的初期化子またはオブジェクトのコンストラクターの内部でのみ設定できるためです (トリックを除けば)。MyData
ここでは、Joe の回答のように新しいインスタンスを初期化します。
MyData x = new MyData("Brown Bear", 0x88, 10);
2 番目のポイント: 一貫性、またはその欠如。C スタイルの constness が壊れているため、C# は C スタイルの constness をサポートしていません。Microsoft の C# 言語チームの元開発者である Eric Lippert は、ここでその点について詳しく説明しています。
本当に、本当に、本当に正当な理由がない限り、C スタイルの constness をエミュレートすることについて心配しない方がはるかに良いと思います。Constness は最終的に、悪意のある人や無知な人によってコードが改ざんされるのを防ぐ方法です。悪意のある人は、あなたが好むと好まざるとにかかわらず、C や C# でデータを変更できるようになります。そして、他者の無知から身を守るためのはるかに優れたツールがあります: カプセル化です!
このテーブルを使用する機能をクラス内にラップし、テーブルをそのクラスのプライベート メンバーにしてから変更しないでください。ある時点でそのテーブルを外の世界に公開する必要がある場合はReadOnlyCollection
、Joe が提案したように使用できます。
public static readonly ReadOnlyCollection<MyData> ReferenceTable = new ReadOnlyCollection<MyData>(new []
{
new MyData(/* whatever */),
new MyData(/* whatever */),
new MyData(/* whatever */),
});
ReadOnlyCollection
他のコレクション (この場合はデータ テーブル) の薄いラッパーです。IList<T>
配列といくつかの組み込みコレクションを含む、インターフェイス を実装する任意のオブジェクトをラップできます。
もう1つの注意:あなたのコメントの1つで、const
Cでテーブルを宣言する理由の1つは、オブジェクトがメモリ内のどこに割り当てられるかに影響するためだと述べました。ここではそうではありません。上記の例でRefData
は、マネージド ヒープで宣言されます。これは配列であり、配列は参照型であるためです。