2012-11-14 47 views
3

我'试图创建一个包含泛型类型
列表的通用类,但我想有null以外的默认值来检查,如果一个项目被删除
名单应该看像这样默认不为空一般价值

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

有什么想法吗?

+1

我无法解析“来检查一个项目是否被删除 该列表应该看起来像这样” –

+0

mmm我的意思是如果我有一些类型的正常数组(字符串)数组中的所有项目都设置为null,如果我添加了一个项目,然后再删除它如何知道那里有一个项目? – user1748906

回答

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 

但无论如何,你无法定义某个项目是否被删除,或者它是否添加了默认值。所以,如果你从不将默认值添加到arra年。

+0

但是,如果我们要使用对象,有泛型的点是什么 – user1748906

+1

@ user1748906同样的问题我想问你 - 看你的样本和我的解释为什么只有对象符合你的需求 –

+0

我想你是对的,你的解决方案的工作原理即使有引用类型,如果我有一个静态只读字段DEFAULT = new object(); – user1748906

3

如果TypeV是不是你的控制之下,然后它可以永远是值类型,在这种情况下,绝对没有,可以用来作为一个标记值(对于引用类型,你可以有一个哨兵值,并使用object.ReferenceEquals来检查一个插槽是否包含它)。这意味着唯一可能的实现是在列表中每个插槽使用一个额外的信息位。

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

+0

我同意。这是不是为什么'可空'被引入? – neontapir

+0

@neontapir:不,不是。如果'TypeV'为'可为空'呢? – Jon

+0

@Jon他并不是说你应该使用'Nullable'作为你的实现,他指的是'Nullable'既包含值又包含一个布尔指示,如果它是“真实”的,并且你使用相同的模型。 – Servy

-2

这是更好地使用字典,然后

List<Tuple<TypeV, bool>> 

,因为你可以在O获取状态(1)。

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

+0

这是如何解决这个问题的? – neontapir

+0

你可以用一个'词典'来表示一个稀疏填充的列表,虽然这个答案实际上没有提供或提供足够的信息来真正成为“答案”。 – Servy