1

An annoying behaviour of ProtoBuff.net is that empty collections are serialised as null. This can create some pretty hard to pin down bugs.

Retrieval of cached values from my application is done with the following function:

public T Get<T>(string cacheKey)
{
    var data = (byte[])Database.StringGet(cacheKey);
    if (data == null)
    {
        return default(T);
    }
    return Serialiser.Deserialise<T>(data);
}

If T is List<int> with zero values, this will return an empty list (because data == null it will return default(List<int>)).

If T is Dictionary<bool, Hashset<int>, where two keys true and false exist but there are no values in the corresponding hashset, the key exists but the value is null.

Is there any way to determine if T contains a collection, and if so return an empty collection instead of null if the collection is empty? Preferably, it would check for an empty collection anywhere in the object, not just if T itself is a collection that contains a collection.

The alternative (that I'm doing now) is to try to remember to check for nulls when I know the explicit type when I get from cache which isn't ideal.

Tom Gullen
  • 61,249
  • 84
  • 283
  • 456
  • Do you know the type you're expecting when you call Get? If so have an overload for this case. – Phil Mar 07 '17 at 17:33

2 Answers2

1

You could use typeof operator.

if(typeof(T)== typeof(Dictioneary))
{
  return whatever you want;
}
Luci
  • 1,278
  • 9
  • 17
0

As per my comment, would something like this help?

void Main()
{
    Get<int>("cacheKey1").Dump();
    Get<List<string>, string>("cacheKey2").Dump();
    Get<Dictionary<string, string>, KeyValuePair<string,string>>("cacheKey3").Dump();
}

public T Get<T>(string cacheKey)
{
    ...
    return default(T);
}

public IEnumerable<S> Get<T, S>(string cacheKey) where T : IEnumerable<S>
{
    ...
    return Enumerable.Empty<S>();
}
Phil
  • 42,255
  • 9
  • 100
  • 100