Specialized Collections such as BitArray, BitVector32, StringCollection and String Dictionary

When dealing with Boolean expression we need to use bits and BitArray is a good class to utilize for this purpose.BitArray is a resizable collection but not dynamically resizable so setting up size of the BitArray is important. However, you can resize by using Length property of the BitArray. In addition, it also supports Boolean operations such as and, or, not, and xor. Unlike ordinary array BitArray does not support Add andRemove since bits are true or false values so no need to manipulate them any other way. BitVector32 helps to manipulate bits in a 32-bit integer and unlike BitArray it’s not resizable. It is set to 32 bits so that it can manipulate bits of the 32 bit integer.

Upon BitArray creation you get an array with all bits set to False by default so you require setting it to true within the code. BitArray is very useful to perform Boolean operations and its done like that
BitArray bits = new BitArray(2);
bits[0] = false;
bits[1] = true;

BitArray moreBits = new BitArray(2);
bits[0] = true;
bits[1] = true;

BitArray xorBits = bits.Xor(moreBits);
foreach (bool bit in xorBits)
{
    Console.WriteLine(bit);
}

BitVector32 is primarily used to modify value of integer and you can do it with the following steps. Create instance of BitVector32 and set it to 0 so that all bits are clear then you need to call BitVector32.CreateMask method to obtain bits one by one and then you can update those bits by setting them to true or false.
BitVector32 vector = new BitVector32(0);
int myFirstBit = BitVector32.CreateMask();
int mySecondBit = BitVector32.CreateMask(myFirstBit);
int myThirdBit = BitVector32.CreateMask(mySecondBit);
vector[myFirstBit] = true;
vector[mySecondBit] = true;
Console.WriteLine("{0} should be 3", vector.Data);
Console.WriteLine(vector);

BitVector32 is also used for BitPacking. If we need to store three small numbers of Int16 we don’t need to create each separately. All we need to do is to arrange BitVector32 in such a way so that it has sections and store each number into individual section.
BitVector32.Section myFirstSection = BitVector32.CreateSection(10);
BitVector32.Section mySecondSection = BitVector32.CreateSection(50, myFirstSection);
BitVector32.Section myThirdSection = BitVector32.CreateSection(500, mySecondSection);
BitVector32 packedBits = new BitVector32(0);
packedBits[myFirstSection] = 20;
packedBits[mySecondSection] = 2;
packedBits[myThirdSection] = 268;
Console.WriteLine(packedBits[myFirstSection]);
Console.WriteLine(packedBits[mySecondSection]);
Console.WriteLine(packedBits[myThirdSection]);

StringCollection is just like an Array but only able to store strings in it. It is also dynamically sized collection and working with this collection is just as simple and similar as working with ArrayList.
StringCollection myCollection = new StringCollection();
myCollection.Add("First");
myCollection.Add("Second");
myCollection.Add("Third");
myCollection.Add("Fourth");
myCollection.Add("fourth");

string theString = myCollection[3];
// No longer need to

StringDictionary class is strongly type dictionary collection. Strongly type means simply that there are restrictions that this dictionary has to follow and in our case it means that we can use it as Hashtable but values can only be strings! Keys are not sensitive for StringDictionary.
StringDictionary myDict = new StringDictionary();
myDict["First"] = "1st";
myDict["Second"] = "2nd";
myDict["Third"] = "3rd";
myDict["Fourth"] = "4th";
myDict["fourth"] = "fourth";
//<- Won't compile...not a string
string converted = myDict["Second"];
// No casting needed

If we need case insensitivity with the regular Hashtable we can do that with the help of CollectionsUtil class
Hashtable inMyTable = CollectionsUtil.CreateCaseInsensitiveHashtable();
inMyTable["hello"] = "Hello1";
inMyTable["HELLO"] = "Hi";
Console .WriteLine(inMyTable.Count); // 1

If we want to ignore current culture on the computer we need to use it like that
Hashtable hash = new Hashtable(StringComparer.InvariantCulture);

One of the more complicated dictionaries is NameValueCollection which uses key/value pair but also you can assign multiple values to a key and reference key/value by index. If we store value with a key, we’ll always add new one but if we try to store it with the indexer’s help we will overwrite value every time we do that.
NameValueCollection myNameValue = new NameValueCollection();
myNameValue.Add("Key", "Some Text");
myNameValue.Add("Key", "More Text");
foreach (string s in myNameValue.GetValues("Key"))
{
    Console.WriteLine(s);
}
//Or by index
for (int × = 0; × < myNameValue.Count; ++×)
{
    Console.WriteLine(myNameValue[x]);
}
myNameValue["First"] = "1";
myNameValue["First"] = "2";
myNameValue.Add("Second", "2nd");
myNameValue.Add("Second", "SECOND");
Console.WriteLine(myNameValue.GetValues("1").Length);// 1
Console.WriteLine(myNameValue.GetValues("2").Length);// 2