So, we discussed Generic Collections in my previous chapter of this series, so let's dive deep into the different types and how to use them.
The syntax is List<T>
, Dictionary<Tkey,TValue>
and so on and as we've said before T just stands for placeholder of the type of generic collection you'd like to create.
Lists
//Create a class of objects we'd like to store.
public class Animal
{
public Animal()
{
}
public int Age { get; set; }
public string Name { get; set; }
public int NumberOfLegs { get; set; }
public string Sound { get; set; }
}
var animals = new List<AnimaL>();
There you have it you've just created a new empty list that will contain only Animal
objects. So how do we fill it with objects, well thats simple and can be done in 2 (two) ways.
//Option 1 - During instantiating the list.
var animals = new List<Animal>
{
new Animal { Name = "Dog", Age =4, NumberOfLegs = 4, Sound = "Bark" },
new Animal { Name = "Cat", Age =14, NumberOfLegs = 4, Sound = "Meow" },
new Animal { Name = "Duck", Age =1, NumberOfLegs = 2, Sound = "Quack" },
new Animal { Name = "Lion", Age =2, NumberOfLegs = 4, Sound = "Roar" }
};
//Option 2 - using the Add() method.
var animals = new List<Animal>();
animals.Add(new Animal { Name = "Dog", Age = 4, NumberOfLegs = 4, Sound = "Bark" });
animals.Add( new Animal { Name = "Cat", Age = 14, NumberOfLegs = 4, Sound = "Meow" });
animals.Add(new Animal { Name = "Duck", Age = 1, NumberOfLegs = 2, Sound = "Quack" });
animals.Add(new Animal { Name = "Lion", Age = 2, NumberOfLegs = 4, Sound = "Roar" });
//usage
var dog = animals[0];
However the downside to using lists is retrieving the objects in this fashion, as we aren't always sure what index the item will be at, and this is where Dictionaries can often come in useful.
Dictionaries - Dictionary
Dictionaries are very useful, and work just like a dictionary that we've all used at school, with a key > value pairing. At school we'll have seen a word (key) and its definition (value), and this is how C# Dictionaries work. We provide it a key, and a value to keep. The value can be any piece of information / object we wish to store. We then use the key to access the record within the collection, instead of an index.
To create a new Dictionary it's as easy as this:
var animalDictionary = new Dictionary<string,Animal>(){
{"Dog",new Animal { Name = "Dog", Age =4, NumberOfLegs = 4, Sound = "Bark" }},
{"Cat",new Animal { Name = "Cat", Age =14, NumberOfLegs = 4, Sound = "Meow" }},
{"Duck", new Animal { Name = "Duck", Age =1, NumberOfLegs = 2, Sound = "Quack" }},
{"Lion",new Animal { Name = "Lion", Age =2, NumberOfLegs = 4, Sound = "Roar" }}
}
//and we can use it like so
var lion = animalDictionary["Lion"];
//or
var lionsSound = animalDictionary["Lion"].Sound;
So you can see here we've created a Dictionary<string,Animal>()
, meaning our key, and thing we can search for quickly is the type of animal as a string, and then the value type is an Animal object.
So when we retrive using a similar index syntax in a list or Array ([]
) we can specify the key and it'll return the value we stored against it just like a Dictionary we used at school.
Queues - Queue
Queues work in just the same way as a queue does in everyday life, with a first-in , first-out approach. Queue<T>
does not implement the ICollection interface like Dictionary and Lists, meaning it doesn't have an Add method. Meaning you cannot add elements to the Queue whilst instantiating, it also means you cannot use the Add*() method, instead you use the Enqueue() method.
var restaurantQueue = new Queue<string>();
restaurantQueue.Enqueue("Front of Queue");
restaurantQueue.Enqueue("Second in Line");
restaurantQueue.Enqueue("3rd in Line");
restaurantQueue.Enqueue("Back of the Line");
//loop over the items and print out
foreach(var customer in restaurantQueue){
Console.WriteLine(customer);
}
Queues have so many other uses though, as really all we've done is create list,and looped over it, so what can we do with a Queue that differs, here are some methods and examples
Queue<string> restaurantQueue = new Queue<string>();
restaurantQueue.Enqueue("Front of the Queue");
restaurantQueue.Enqueue("Second");
restaurantQueue.Enqueue("Third");
restaurantQueue.Enqueue("At the back of queue");
//Let in the next person at the front of the queue and then they're no longer in the queue
Console.WriteLine($"Allow in and remove from the queue: { restaurantQueue.Dequeue() }");
Console.WriteLine($"Allow in and remove from the queue: { restaurantQueue.Dequeue() }");
//Peek at the first person in the queue without removing them - maybe the restaurant wants to check something without losing their place
Console.WriteLine($"Person at the front of the queue is : {restaurantQueue.Peek()}");
//Clear the queue
restaurantQueue.Clear();
//Check if someone is in the queue
var queenInQueue = restaturantQueue.Contains("Queen");
Console.WriteLine($"The queen is in the queue = {queenInQueue}");
Stacks - Stack
Stacks are the opposite of a queue, in that they work on a last-in first-out approach.
var stack = new Stack<string>();
stack.Push("first");
stack.Push("two");
stack.Push("three");
stack.Push("four");
stack.Push("last");
foreach( string number in stack )
{
Console.WriteLine(number);
}
//Ouput: last four three two first
Again we want to utilise the Stack methods, so like the queue we don't use the Add() method, we have a Push method instead, and to use and remove instead of Dequeue() we have Pop().
var stack = new Stack<string>();
stack.Push("first");
stack.Push("two");
stack.Push("three");
stack.Push("four");
stack.Push("last");
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Peek());
//Ouput last four
Other things you can do with collections
Remove
var animals = new List<Animal>
{
new Animal { Name = "Dog", Age =4, NumberOfLegs = 4, Sound = "Bark" },
new Animal { Name = "Cat", Age =14, NumberOfLegs = 4, Sound = "Meow" },
new Animal { Name = "Duck", Age =1, NumberOfLegs = 2, Sound = "Quack" },
new Animal { Name = "Lion", Age =2, NumberOfLegs = 4, Sound = "Roar" }
};
animals.RemoveAt(2); // removes the item at index #2 (Duck)
//Remove an item using the item - say you'd loaded it out but then want to remove it after doing something with it, i.e get its name.
var dog = animals.[0];
var dogsName = dog.Name;
animals.Remove(dog);
Sort Lists, these are available on any collection that implements the IComparable interface
var animals = new List<Animal>
{
new Animal { Name = "Dog", Age =4, NumberOfLegs = 4, Sound = "Bark" },
new Animal { Name = "Cat", Age =14, NumberOfLegs = 4, Sound = "Meow" },
new Animal { Name = "Duck", Age =1, NumberOfLegs = 2, Sound = "Quack" },
new Animal { Name = "Lion", Age =2, NumberOfLegs = 4, Sound = "Roar" }
};
animals.Sort((x, y) => x.Name.CompareTo(y.Name));
foreach (var animal in animals)
{
Console.WriteLine(animal.Name);
}
Here we're using the Sort method, which takes in a comparer. In our case we're passing it an anonmous method, that is taking (x,y)
and it will compare x.Name to y.Name. Y
is the next element in the list, so it will compare using the default comparer (ascending) for a string, and sort the items in alphabetical order.
Summary
I hope you have a better understanding of how we can use Generic collections, now go out there and build a console application and start playing with generic collections.
As always if you have any questions, or want updates on upcoming chapters, or just want to communicate with me, don't forget to follow me on twitter at @Gweaths