简体   繁体   English

默认不是null通用值

[英]default not null generic value

I'am trying to create a generic class that contains a list of generic type 我正在尝试创建一个包含泛型类型列表的泛型类
but i want to have a default value other than null to check if an item been deleted 但我希望有一个非null的默认值来检查项目是否被删除
the list should look like this 列表应该如下所示

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

any ideas ? 有任何想法吗 ?

If TypeV is not under your control then it can always be a value type, in which case there is absolutely no value that can be used as a sentinel (for reference types, you can have a sentinel value and use object.ReferenceEquals to check if a slot contains it). 如果TypeV不在你的控制之下,那么它总是一个值类型,在这种情况下绝对没有可以用作标记的值(对于引用类型,你可以有一个sentinel值并使用object.ReferenceEquals来检查是否一个插槽包含它)。 Which means that the only possible implementation is to use one additional bit of information per slot in the list. 这意味着唯一可能的实现是在列表中每个插槽使用一个额外的信息位。

A reasonable choice would be to keep a List<Tuple<TypeV, bool>> and use the bool as a "deleted" flag. 一个合理的选择是保持List<Tuple<TypeV, bool>>并将bool用作“已删除”标志。

For reference type default value will be null (you can't define if value was never used, or it was deleted). 对于引用类型,默认值将为null (您无法定义是否从未使用过值,或者它已被删除)。 So your idea will not work for generic parameters of reference type. 因此,您的想法不适用于引用类型的泛型参数。 On the other hand you can't have null values for non-reference types. 另一方面,非引用类型不能包含空值。 So, the only option is an array of objects (it can hold both nulls and value types): 因此, 唯一的选择是一个对象数组 (它可以包含空值和值类型):

// 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);
   }
}

And

Foo<int> foo = new Foo<int>();
foo.Add(1, 0);
foo.Add(2, 3);
foo.Add(3, 4);
foo.Delete(3);

At this point values will be: 此时values将为:

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

But anyway you can't define if some item was deleted, or it was added with default value.. So, your idea will work if you never add default values to array. 但无论如何你无法定义某个项目是否被删除,或者它是否添加了默认值..所以,如果你从未向数组添加默认值,你的想法将起作用。

It is better to use dictionary then 那么最好使用字典

List<Tuple<TypeV, bool>>

because you can get the status in O(1). 因为你可以在O(1)中获得状态。

or just use HashSet and when you want to check if item is deleted use Contains(item). 或者只是使用HashSet,当你想检查项目是否被删除时,使用Contains(item)。 this also work at O(1). 这也适用于O(1)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM