user1748906
user1748906

Reputation: 526

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
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 ?

Upvotes: 3

Views: 973

Answers (3)

shanif
shanif

Reputation: 464

It is better to use dictionary then

List<Tuple<TypeV, bool>>

because you can get the status in O(1).

or just use HashSet and when you want to check if item is deleted use Contains(item). this also work at O(1).

Upvotes: -2

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

For reference type default value will be null (you can't define if value was never used, or it was deleted). 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:

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.

Upvotes: 1

Jon
Jon

Reputation: 437326

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). 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.

Upvotes: 4

Related Questions