Web Design that taps into the haromny and vision of your dreams.

C# Advanced Data Types

A look at some powerful advanced data types

Written By on in C#

813 words, estimated reading time 4 minutes.

As well as common data types such as strings and integers, the .Net Framework provides a number of advanced data types which provide a means of utilising common data structures more easily and make life a lot easier for the developer. In this article, we will look at hash tables, dictionaries, enums, and compare usage of string concatenation vs a StringBuilder data type.

Advanced C# Programming Series
  1. C# Advanced Data Types
  2. Using C# Properties and Indexers
  3. C# Event Handling and Delegates
  4. Method Overloading and Overriding in C#
  5. C# Class Abstraction and Encapsulation
  6. C# Aggregation and Advanced Scope Techniques
  7. Polymorphism in C#
  8. Boxing and Unboxing Value Types in C#
  9. C# Operator Overloading
  10. Creating Multi-Threading Applications with C#
  11. Unsafe Code Execution in Microsoft .Net

Hashtables

Hash tables are a named key List where you define a key and a value when setting and getting values. Hash tables are not type safe, so the key and value are of type object. You can access the data using the named key as the index; however you will have to check and cast the value.

using System;
using System.Text;
using System.Collections;
 
class Program
{
    static void Main()
    {
        Hashtable myHashTable = new Hashtable();
 
        myHashTable.Add("bob", 27);
        myHashTable.Add(33, "fred");
 
        int theAge = (int)myHashTable["bob"];
    }
}

In order to iterate through hash table elements you must create a IDictionaryEnumerator interface to retrieve the key and the value.

IDictionaryEnumerator myEnumerator = new myHashTable.GetEnumerator();
 
while (myEnumerator.MoveNext())
{
  Console.WriteLine("{0}: {1}", myEnumerator.Key, myEnumerator.Value);
}

You can also use a foreach loop like this:

foreach (string key in myHashTable.Keys)
{
  Console.WriteLine(key + '=' + myHashTable[key]);
}

Dictionary

A dictionary is a type-safe version of the Hashtable. Like a List<> object, you need to specify the type for both the key and the value.

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
 
class Program
{
    static void Main()
    {
        Dictionary<string, int> myDictionary = new Dictionary<string, int>();
 
        myDictionary.Add("bob", 27);
        myDictionary.Add("fred", 33);
 
        int theAge = myDictionary["bob"];
    }
}

Enums and Flags

An enum or enumerate is a set consisting only of defined constants. They are useful for limiting the values that a type can contain.

enum daysInWeek {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

Each item in the set is assigned a numerical value, in this example Monday equals 1 and Sunday = 7. You can specify your own values using the equal's symbol followed by a numeric.

enum daysInWeek {Monday=0, Tuesday=2, Wednesday=4, Thursday, Friday, Saturday, Sunday};

Values that have not been explicitly assigned a value take the value of the previous item plus one, thus Thursday will equal 5.

Enums can be used as constants to ensure that only the specified values are allowed.

int day = daysInWeek.Wednesday;
 
if (day == daysInWeek.Thursday)
{
  Console.WriteLine("Today is Thursday");
}

Enums can also be used to define a binary set, which is a value that holds various options about something using the [Flags] attribute. These are useful where there are many boolean options that an object can have and cut down on the number of properties that a call will have.

bool hasButtons = true;
bool hasZip = false;
bool hasPockets = false;
bool hasEmbrodery = true;

Rewritten using enum bit flags gives:

 
[Flags]
public enum garmentOptions
{
  hasButtons = 0x01,   // 00000001  1
  hasZip = 0x02,       // 00000010  2
  hasPockets = 0x04,   // 00000100  4
  hasEmbrodery = 0x08; // 00001000  8
}
 
garmentOptions myGarment = garmentOptions.hasButtons | garmentOptions.hasEmbrodery;
 
// result of myGarment is 9 or:
//   00000001  1 - hasButtons 
// + 00001000  8 - hasEmbrodery
// = 00001001  9
 
if ((myGarment & garmentOptions.hasEmbrodery) > 0)
{
  // Embrodery specific code here
}

The logical bitwise & is used to test if an enum bit flag is part of the set in myGarment.

String vs StringBuilder

A string data type is an immutable type; meaning that once it is created it cannot be changed. Strange, you may think, I do that all the time...

string name = "bob";
name = name + " smith";
name += " jr";

While the compiler sees no problems with this, it's not the most efferent method. Since the string object cannot be changed, the CLR will create a new string object; assign it the value of the old one plus the extra data, then dispose of the old object. If you are doing multiple operations, such as building up a result string, then this method represents a performance overhead that can be eliminated by using a StringBuilder.

StringBuilders allow the string to be manipulated without objects being created and disposed of each time. They can then be converted back to a string when needed.

StringBuilder myStringBuilder = new StringBuilder();
 
myStringBuilder.Append("bob");
myStringBuilder.Append(" smith");
myStringBuilder.Append(" jr");
 
string myString = myStringBuilder.ToString();

There is a huge performance hit when appending to a string and the speed increase from using a string builder is surprising. You can have a look at the performance increase by running this short piece of code. It will append a full stop to the previous string 100000 times.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string myString = "";
            StringBuilder mySb = new StringBuilder();
 
            Console.WriteLine("String Start: {0}", System.DateTime.Now);
 
            for (int i = 0; i < 100000; i++)
            {
                myString += ".";
            }
 
            Console.WriteLine("String End: {0}", System.DateTime.Now);
            Console.WriteLine("StringBuilder Start: {0}", System.DateTime.Now);
 
            for (int i = 0; i < 100000; i++)
            {
                mySb.Append(".");
            }
 
            Console.WriteLine("StringBuilder End: {0}", System.DateTime.Now);
        }
    }
}
 
String Start: 11/11/2011 20:57:56
String End: 11/11/2011 20:58:12
StringBuilder Start: 11/11/2011 20:58:12
StringBuilder End: 11/11/2011 20:58:12
Press any key to continue . . .

Last updated on: Friday 23rd June 2017

 

Comments

There are no comments for this post. Be the first!

 

Leave a Reply

Your email address will not be published.





If you find something abusive or that does not comply with our terms or guidelines please flag it as inappropriate.

Copyright © 2001-2018 Tim Trott, all rights reserved. Web Design by Azulia Designs

This web page is licensed for your personal, private, non-commercial use only.

Disclaimer, Privacy & LegalSitemapContact Me