4

I am getting NullReferenceException at the _dicCache.TryGetValue(objID, out newObject); line. And I have no Idea why this is happening at all. Can comeone point me to the right direction please?

Here is my class:

public class Cache<T>
{
    public string Name { get; set; }

    private  Dictionary<int, T> _dicCache = new Dictionary<int, T>();

    public  void Insert(int objID, T obj)
    {
        try
        {
            _dicCache.Add(objID, obj);

            HttpContext.Current.Cache.Insert(Name, _dicCache, null, DateTime.Now.AddMinutes(10), TimeSpan.FromMinutes(0));
        }
        catch (Exception)
        {
            throw;
        }
    }

    public bool Get(int objID, out T obj)
    {
        _dicCache = (Dictionary<int, T>)HttpContext.Current.Cache.Get(Name);


        try
        {
            return _dicCache.TryGetValue(objID, out obj);
        }
        catch (Exception)
        {
            throw;
        }
    }
 }

And here is how I call it:

   Services.Cache<Entities.User> cache = new Services.Cache<Entities.User>();
   cache.Name = Enum.Cache.Names.usercache.ToString();


   Entities.User user = new Entities.User();

   cache.Get(pUserId, out user);

I Also have tried to change to Get class to:

    public T Get(int objID, out T obj)
    {
        _dicCache = (Dictionary<int, T>)HttpContext.Current.Cache.Get(Name);

        T newObject = (T)Activator.CreateInstance<T>();


        try
        {
            _dicCache.TryGetValue(objID, out newObject);

            obj = newObject;

            return obj;
        }
        catch (Exception)
        {
            throw;
        }
    }

But I still get the same NullReferenceException at the _dicCache.TryGetValue(objID, out newObject); line.

rpmlins
  • 135
  • 2
  • 9
  • 5
    `_dicCache` is probably null. Are you sure `(Dictionary)HttpContext.Current.Cache.Get(Name);` this cast is valid? Debug these lines – horgh Dec 26 '12 at 00:12
  • You needn't to initialize `newObject`, as it is initialized by `TryGetValue`. The problem is definitely not with it. – horgh Dec 26 '12 at 00:14
  • @Konstantin Vasilcov `_dicCache` is `null`! I didn't pay Attention to that. Thank you very much. – rpmlins Dec 26 '12 at 00:17
  • Since I declare the `_dicCache` variable like this: `private Dictionary _dicCache = new Dictionary();` I thought it wouldn't be null. Can you explain why it is null? – rpmlins Dec 26 '12 at 00:26
  • Is there anything at all found by that `Name`in the cache? – horgh Dec 26 '12 at 00:30

2 Answers2

8

I think the only way you could have that exception is if your dictionary is null.

_dicCache.TryGetValue(objID, out newObject);

null is not a valid argument for the key (if TKey is a reference type), though in your case it's int so cannot be null. You'd see an ArgumentNullException if passing a null value for key anyway.

Are you sure _dicCache is not null? I would check the value of the assignment:

_dicCache = (Dictionary<int, T>)HttpContext.Current.Cache.Get(Name);
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • yes my _dicCache is null :(. trying to solve this... Since I declared the _dicCache variable like this: private Dictionary _dicCache = new Dictionary(); I thought it wouldn't be null – rpmlins Dec 26 '12 at 00:28
  • 1
    @rpmlins, I'm guessing the assignment from `HttpContext.Current.Cache` is setting it to `null`. – Drew Noakes Dec 26 '12 at 00:29
  • Well, someone does not seem to like me. If you look at my answer below, it explains exactly this. In your Insert method, you put _dicCache in the http context. In your Get method, you overwrite the member _dicCache variable from what is inside the http context cache, and that is always null because you never call the Insert method. – Ameen Dec 26 '12 at 00:30
  • `_dicCache = (Dictionary)HttpContext.Current.Cache.Get(Name);` will always return null unless the `Insert` method is called which puts the non-null _dicCache into the http context's cache. – Ameen Dec 26 '12 at 00:33
  • @AmeenTayyebiJazayeri, have an upvote from me. – Drew Noakes Dec 26 '12 at 00:33
  • @Drew Noakes thx. now I validate the _dicCache checking if its null before. – rpmlins Dec 26 '12 at 01:13
  • Glad you got it working. – Drew Noakes Dec 26 '12 at 13:40
  • > null is a valid argument for the key (if TKey is a reference type), though in your case it's int. I had thought the same, but it seems this is not true. See https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.trygetvalue?view=net-8.0 – myavuzselim Apr 19 '23 at 10:02
  • @myavuzselim quite right! Updated. Thanks. – Drew Noakes Apr 20 '23 at 02:36
1

The method that actually puts _dicCache into the http context's cache is the insert method which is never called in your code, hence when you try to obtain it back from the http context, you get null (you only ever call Get).

I would change the Name setter to actually put the dictionary into the http context at that time, or better yet, if you can somehow insert the dictionary into the cache in the constructor by getting the Name property as a constructor parameter. In general, I try to design classes in such a way that they are in an "uninitialized" state for the least amount of time possible.

Ameen
  • 2,576
  • 1
  • 14
  • 17
  • hey @Ameen I apretiate your answer but I am not calling the insert method as I've stated on my question. I am just Calling the Get method. That was on purpose. I only insert if the object is not in the _dicCache . So I always call the Get first. – rpmlins Dec 26 '12 at 01:12