ジェネリック型のリストを含むジェネリッククラスを作成しようとして
いますが、アイテムが削除されたかどうかを確認するためにnull以外のデフォルト値が
必要です。リストは次のようになります。
0 TypeV (some value of TypeV)
1 null
2 null (never been used)
3 default (deleted)
4 TypeV
何か案は ?
が制御下にない場合TypeV
は、常に値型にすることができます。その場合、番兵として使用できる値はまったくありません(参照型の場合、番兵値を使用object.ReferenceEquals
して、スロットにその値が含まれているかどうかを確認できます。 )。つまり、可能な実装は、リスト内のスロットごとに1ビットの追加情報を使用することだけです。
合理的な選択は、を保持し、「削除済み」フラグとしてList<Tuple<TypeV, bool>>
使用することです。bool
参照型の場合、デフォルト値は次のようになりますnull
(値が使用されなかったのか、削除されたのかを定義することはできません)。したがって、あなたのアイデアは、参照型のジェネリックパラメータでは機能しません。一方、非参照型にnull値を設定することはできません。したがって、唯一のオプションはオブジェクトの配列です(nullと値型の両方を保持できます)。
// TODO: check for index fit array range
public class Foo<T>
where T : struct
{
object[] values = new object[5];
public void Add(T value, int index)
{
// TODO: do not allow to add default values to array
values[index] = value;
}
public void Delete(int index)
{
values[index] = default(T);
}
}
と
Foo<int> foo = new Foo<int>();
foo.Add(1, 0);
foo.Add(2, 3);
foo.Add(3, 4);
foo.Delete(3);
この時点で次のvalues
ようになります。
0 1 (some value of T)
1 null (never been used)
2 null (never been used)
3 default (deleted)
4 3
ただし、いずれにせよ、一部のアイテムが削除されたのか、デフォルト値で追加されたのかを定義することはできません。したがって、配列にデフォルト値を追加しない場合でも、アイデアは機能します。
その後、辞書を使用することをお勧めします
List<Tuple<TypeV, bool>>
O(1)でステータスを取得できるからです。
または、HashSetを使用し、アイテムが削除されているかどうかを確認する場合は、Contains(item)を使用します。これはO(1)でも機能します。