特定のデータを受け取って処理をするジェネリッククラス/メソッドを作りたかったので、以下宣言をしました。
c#
1// 受け取れるデータのインターフェイス(値取得しかしないメソッドを持つ) 2public interface IMark { 3 bool IsMarkXyz(); 4} 5 6// IMarkを受け取ってなんやかんやする処理クラス 7// 引数の内容の書き換えは絶対にしない(例えばListを持っていても追加したりもしない) 8public class Executer { 9 public bool Execute1<T>(T data) where T : IMark { /* 処理 */ } 10 public bool Execute2(IMark data) { /* 処理 */ } 11 public bool Execute3<T>(in T data) where T : IMark { /* 処理 */ } 12 public bool Execute4<T>(IEnumerable<T> data) where T : IMark { /* 処理 */ } 13}
そのデータはイミュータブルでよく、サイズが十分小さそうだったので、以下宣言をしました。
c#
1public readonly struct HogeData : IMark { 2 // データの例 3 public int Id { get; } 4 public string Text { get; } 5 public HogeData(int id, string text) { Id = id; Text = text; } 6 7 public bool IsMarkXyz() { /* IMarkに既定された、値を取得する処理 */ } 8}
ここで、readonly struct と in引数の理解がちゃんとできているか自信がないです。
特に、inで受け取らないメソッドにreadonly structの変数を渡したときの動作がよくわかりません。
メモリ管理、Defensive copy、ボックス化について以下の内容であっているか確認させてください。
?がついているのは自信がない部分です。
c#
1 HogeData hoge = new HogeData(0, "Xyz"); // 構造体は値型なのでスタックにある。 2 hoge.IsMarkXyz(); // -> readonly structなのでDefensive copyは起きない。 3 4 IMark hoge2 = new HogeData(1, "abc"); // Box化が起きてヒープに行く。 5 hoge2.IsMarkXyz(); // -> ヒープ化は起きているが中身はreadonly structなのでDefensive copyは起きない? 6 7 var exe = new Executer(); 8 exe.Execute1<HogeData>(hoge); // -> Execute1はinで受け取らないので、コピーが起きる??? 9 exe.Execute2(hoge); // -> ボックス化が起きる。参照型になっているためコピーされない。 10 exe.Execute3<HogeData>(in hoge); // -> inで受け取るメソッドに渡しているのでコピーは起きない。 11 exe.Execute4<HogeData>(new[] { hoge }); // -> 配列は参照型なのでヒープに行き、コピーは起きない?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/02 01:03
2021/02/02 01:59
2021/02/02 07:38
2021/02/02 08:08