プロダクトコードを触っていると、struct がたまに出てくるが class との違いがよくわかっていなかったのでメモ
公式ドキュメント
公式は正義
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/struct
構造体について
公式によると、
"構造体型" (または "構造体型") とは、データおよび関連する機能をカプセル化できる 値の型です。 構造体型を定義するには、struct キーワードを使用します。
と記載されており、値の型として実装される。
この部分が class との違いになりそう
定義するには、struct キーワードを使用する
public struct HogeStruct { public string x { get; set; } public int y { get; set; } public HogeStruct(string x, int y) { this.x = x; this.y = y; } } public static void Main(string[] args) { // コンストラクタで値を定義 var hogeStruct = new HogeStruct("test", 3); // オブジェクト初期化しで値を定義 var hogeStruct = new HogeStruct { x = "test", y = 1 }; }
実装にはコンストラクタ、オブジェクト初期化子両方で実装できる
このあたりは、クラスと扱いは同じそう
もちろんreadonly
をつけて読み取り専用にもできる
public readonly struct HogeReadOnlyStruct { public string x { get; set; } public int y { get; set; } public HogeStruct(string x, int y) { this.x = x; this.y = y; } }
WITH
C# 10.0 からは値をコピーして変更するwith
というものもあるらしい
var hogeStruct = new HogeStruct { x = "test", y = 1 }; var hogeStruct2 = hogeStruct with { x = "useWith" }; // hogeStruct2.x = "useWith" // hogeStruct2.y = 1
インスタンス化
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/struct#instantiation-of-a-structure-type
通常、構造体は使用する前にnew
演算子を使用して初期化する必要があるが、
(ここは class と同じ)
構造体のフィールド全てにアクセスできる場合は
new
演算子なしでインタンス化できる
public static class StructWithoutNew { public struct Coords { public int x; public int y; } public static void Main() { Coords p; p.x = 3; p.y = 4; } }
制限事項
基本的には class と同じように使えるらしいが、
class に対していくつかの制限事項がある
その中の一つがパラメータなしのコンストラクタを実装できないとこにある
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/struct#limitations-with-the-design-of-a-structure-type
理由としては
構造体では、すでにパラメータありのコンストラクタがすでに実装されているようで、
後から引数なしでは実装できないとのこと
(C# 10.0 からは可能らしい)
Structはclassと同じように扱えるようで、 異なる部分が多い
そのためか、class と比較した記事ををよく見かける
classと使い分けるにはその辺も整理しなければならなそうなので
その部分は別途、記事としてまとめようと思う