tags:

views:

269

answers:

4

I'm using .Net 2.0, and I've run into a strange error:

I have a hashtable using string as keys and a class (named Market) as the value. The class contains 4 integers and 1 byte. One of the integers represents a counter which I need to increment.

I have only one element in the hashtable. It's key is "Tomo".

I do this:

string strM = "Tomo"
Market mkt = (Market)mHash[strM];
mkt.nCounter++;

In the last line I get an null reference exception, even though using the debugger I can see that the hashtable contains that instance. This code was working fine a week ago.

+2  A: 

Locate the place where you do one of the following:

mHash[strM] = mkt;
mHash.Add(strM, mkt);

At that location, mkt is null.

Edit: This is based on the fact that you stated that you verified the Hashtable contains the key. If in fact the Hashtable did not contain the key, the following applies:

If the specified key is not found, attempting to get it returns null.

280Z28
It contains the key which is not null, even a function before uses that instance of the class.
Roman Dorevich
Check again - it's not the key that's null, it's the value `mkt` that's null. Also, is the `NullReferenceException` thrown even when you have a breakpoint set on the line `Market mkt = (Market)mHash[strM];`? This is a key piece of information in the puzzle.
280Z28
+1  A: 

Since you're using .NET 2.0, I recommend using a Dictionary<string, Market> instead of a HashTable. It will provide type safety, and probably help you realize why you are having the issue in this case.

Reed Copsey
The casting to type will be done anyhow, so what is the benfit from this solution ? can u explain more ?
Roman Dorevich
You avoid boxing, which can cause (potentially) some issues like you're seeing. You also get type safety - so you make sure that both the code that's adding to the collection, as well as the receiving side, are doing things the same way. In your case, you're probably either adding in a null reference, adding in with the wrong key, or retrieving with the wrong key. Having type safety helps the compiler check the most common mistakes in this process. As a side benefit, you'll get better performance with generics, since you avoid boxing.
Reed Copsey
It makes for more readable, easier to debug code. (Also, the runtime will already know beforehand that the object can be cast to the needed type, which saves it from checking)
Thorarin
In this case, there is no boxing going on though. Market class for values (ref type) and strings for keys (ref type).
Thorarin
Thanks for the explanation
Roman Dorevich
@Thorarin: That's true - no boxing with strings or "Market", unless "market" is a struct instead of a class.
Reed Copsey
Is using enumorator is safety on .NET 2.0 ?
Roman Dorevich
You can enumerate the dictionary in .NET 2.0 with full type safety.
Reed Copsey
A: 

Are you sure you're not just looking at the key in the Hashtable, where the value is null?

For example, this works:

mHash["Tomo"] = null;
Market value = (Market)mHash["Tomo"];
value.nCounter++; // NullReferenceException
codekaizen
I'm sure it contains an instance of a class.
Roman Dorevich
One of your assumptions must be wrong, or you wouldn't be getting this error :)
Thorarin
A: 

Maybe you added your instance backward.

mHash.Add(instance, "Tomo")

instead of

mHash.Add("Tomo", instance)

So when you are in debugger, it may appear as if it's listed, but the key is actually the instance and "Tomo" is the object value.

Chris Persichetti