nullable types don't come for free, they take more memory and more cycles, as they have to store and process the data that goes with the extra functionality (think of it as one extra boolean flag "hasValue",
it would double the footprint of an int, double the amount of data to be copied when performing nullable int=nullable int, etc).
you may have to account for changes in "hasValue" too; i.e. a variable that goes from "hasNoValue" to "hasValue" has definitely changed (and if you allow the reverse change, from "hasValue" to "hasNoValue", that would be a change too). So your history information should not be just "oldValue" but also "oldHasValue". Hence
Public shared Function HasChanged(ByVal val1 as Single, ByVal val2 as Nullable(Of Int32)) As Int16
IMO should be more like (I'm no VB expert!):
<br />Public shared Function HasChanged(ByVal val1 as Nullable(Of Int32), ByVal val2 as Nullable(Of Int32)) As Bool<br /> if val1.HasValue AND val2.HasValue return val1<>val2 ' value changed<br /> if val1.HasValue <> val2.HasValue return True ' hasValue changed<br /> return False ' was and is without value<br />End Function<br />
Some more remarks:
1. Try to avoid ToString. if Key is already a string, no need to call ToString on it.
2. I'm not sure having two different collections (one of them a HashTable/Dictionary) is wise; I would try and figure a way with just one. More in particular, if current value and previous value is a characteristic of your objects, I would incorporate that in the object itself, not delegate it to some HashTable. A simple For Each would then suffice.
3. While doing (2) I would not use nullable types, instead I would add an explicit bool flag to my objects. As I expect my code would be more efficient than the general-purpose nullable support (see first alinea).