默认不是null通用值

时间:2012-11-14 21:09:54

标签: c# generics

我正在尝试创建一个包含泛型类型列表的泛型类 但我希望有一个非null的默认值来检查项目是否被删除
列表应该如下所示

0 TypeV   (some value of TypeV)
1 null
2 null    (never been used)
3 default (deleted)
4 TypeV

任何想法?

3 个答案:

答案 0 :(得分:3)

如果TypeV不在你的控制之下,那么它总是一个值类型,在这种情况下,绝对没有可以用作哨兵的值(对于参考类型,你可以有一个哨兵值和使用object.ReferenceEquals检查插槽是否包含它。这意味着唯一可能的实现是在列表中的每个插槽中使用一个额外的信息位。

合理的选择是保留List<Tuple<TypeV, bool>>并将bool用作“已删除”标记。

答案 1 :(得分:1)

对于引用类型,默认值为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

但无论如何你无法定义某个项目是否被删除,或者是否添加了默认值..所以,如果你从不向数组添加默认值,你的想法就会有效。

答案 2 :(得分:-2)

最好使用字典

List<Tuple<TypeV, bool>>

因为你可以在O(1)中获得状态。

或只是使用HashSet,当您想要检查项目是否被删除时,请使用Contains(item)。这也适用于O(1)。