Very roughly: the class
is obsolete version
with functionality very similar to the generic class
created before generic were implemented in v.2.0 of the .NET Framework.
This class was not formally marked by the
attribute, because there is nothing wrong with it; and it can be used in legacy code, but using it in new code is totally pointless. Generics are way better, because you don't need to use error-prone typecasts. Instead, choose from these three classes
They are different in implementations, but, from the standpoint of the using code, they are different mainly in the different trade-off between performance and redundancy.