Creating sorted sets with C# .NET

The SortedSet of T object is the sorted version of the HashSet object. We’ve already seen what a HashSet can do for you in the referenced post. A SortedSet keeps the elements in increasing order.

Consider the following integer set:

SortedSet<int> sortedInts = new SortedSet<int>();
sortedInts.Add(1);
sortedInts.Add(4);
sortedInts.Add(3);
sortedInts.Add(1);
sortedInts.Add(3);
sortedInts.Add(10);
sortedInts.Add(8);
sortedInts.Add(3);
sortedInts.Add(1);
sortedInts.Add(4);
foreach (int i in sortedInts)
{
	Debug.WriteLine(i);
}

This will print…

1
3
4
8
10

Notice that duplicates were rejected to ensure uniqueness just like in the case of HashSets.

That is straightforward for primitive types like integers since .NET “knows” how to compare them. It can decide whether 10 is greater than 5, we don’t need to provide any help.

However what about reference types like your own objects, such as this one?

public class Band
{
	public string Name { get; set; }
	public int YearFormed { get; set; }
	public int NumberOfMembers { get; set; }
	public int NumberOfRecords { get; set; }
}

How can .NET decide on the ordering of your objects? We’ll need to give it a hint by providing an object which implements the generic IComparer of T interface like we saw in this post. We’ll let the Band objects be sorted by their names:

public class BandNameComparer : IComparer<Band>
{
	public int Compare(Band x, Band y)
	{
		return x.Name.CompareTo(y.Name);
	}
}

Let’s see this in action:

SortedSet<Band> bands = new SortedSet<Band>(new BandNameComparer());
bands.Add(new Band() { YearFormed = 1979, Name = "Great band", NumberOfMembers = 4, NumberOfRecords = 10 });
bands.Add(new Band() { YearFormed = 1985, Name = "Best band", NumberOfMembers = 5, NumberOfRecords = 15 });
bands.Add(new Band() { YearFormed = 1985, Name = "Well known band", NumberOfMembers = 5, NumberOfRecords = 15 });
bands.Add(new Band() { YearFormed = 1979, Name = "Famous band", NumberOfMembers = 4, NumberOfRecords = 10 });
bands.Add(new Band() { YearFormed = 1979, Name = "Great band", NumberOfMembers = 4, NumberOfRecords = 10 });
bands.Add(new Band() { YearFormed = 1985, Name = "Best band", NumberOfMembers = 5, NumberOfRecords = 15 });
bands.Add(new Band() { YearFormed = 1985, Name = "Best band", NumberOfMembers = 5, NumberOfRecords = 15 });
bands.Add(new Band() { YearFormed = 1979, Name = "Great band", NumberOfMembers = 4, NumberOfRecords = 10 });
bands.Add(new Band() { YearFormed = 1979, Name = "Famous band", NumberOfMembers = 4, NumberOfRecords = 10 });

foreach (Band band in bands)
{
	Debug.WriteLine(band.Name);
}

This will print…

Best band
Famous band
Great band
Well known band

…so not only were the items sorted by their names but the non-unique values were rejected as well. The IComparer argument also provided a way to declare equality.

View all various C# language feature related posts here.

Using the KeyedCollection object in C# .NET

The abstract generic KeyedCollection object can be used to declare which field of your custom object to use as a key in a Dictionary. It provides sort of a short-cut where you’d want to organise your objects in a Dictionary by an attribute of that object.

Let’s take the following object as an example:

public class CloudServer
{
	public string CloudProvider { get; set; }
	public string ImageId { get; set; }
	public string Size { get; set; }
}

The Image IDs are always unique so the ImageId property seems to be a good candidate for a dictionary key.

Here’s an example:

Read more of this post

Using the HashSet of T object in C# .NET to store unique elements

The generic HashSet of T is at first sight a not very “sexy” collection. It simply stores objects with no order, index or key to look up individual elements.

Here’s a simple HashSet with integers:

HashSet<int> intHashSet = new HashSet<int>();
intHashSet.Add(1);
intHashSet.Add(3);
intHashSet.Add(5);
intHashSet.Add(2);
intHashSet.Add(10);

HashSets can be handy when you want to guarantee uniqueness. The following example will only put the unique integers in the set:

Read more of this post

Using the KeyedCollection object in C# .NET

The abstract generic KeyedCollection object can be used to declare which field of your custom object to use as a key in a Dictionary. It provides sort of a short-cut where you’d want to organise your objects in a Dictionary by an attribute of that object.

Let’s take the following object as an example:

public class CloudServer
{
	public string CloudProvider { get; set; }
	public string ImageId { get; set; }
	public string Size { get; set; }
}

The Image IDs are always unique so the ImageId property seems to be a good candidate for a dictionary key.

Here’s an example:

Read more of this post

Getting notified when collection changes with ObservableCollection in C# .NET

Imagine that you’d like to be notified when something is changed in a collection, e.g. an item is added or removed. One possible solution is to use the built-in .NET generic collection type ObservableCollection of T which is located in the System.Collections.ObjectModel namespace. The ObservableCollection object has an event called CollectionChanged. You can hook up an event handler to be notified of the changes.

If you don’t know what events, event handlers and delegates mean then start here.

Let’s see a simple example with a collection of strings:

Read more of this post

Customise your list by overriding Collection of T with C# .NET

Imagine that you’d like to build a list type of collection where you want to restrict the insertion and/or deletion of items in some way. Let’s say we need an integer list with the following rules:

  • The allowed range of integers is between 0 and 10 inclusive
  • A user should not be able to remove an item at index 0
  • A user should not be able to remove all items at once

One possible solution is to derive from the Collection of T class. The generic Collection of T class in the System.Collections.ObjectModel namespace provides virtual methods that you can override in your custom collection.

The virtual InsertItem and SetItem methods are necessary to control the behaviour of the Collection.Add and the way items can be modified through an indexer:

Read more of this post

Using immutable collections for thread-safe read-only operations in .NET

Sometimes you have a scenario where multiple threads need to read from the same shared collection. We’ve looked at the 4 concurrent, i.e. thread-safe collection types on this blog that are available in the System.Collections.Concurrent namespace. They can be safely used for both concurrent writes and reads.

However, if your threads strictly only need to read from a collection then there’s another option. There are collections in the System.Collections.Immutable namespace that are immutable, i.e. read-only and have been optimisied for concurrent read operations.

Read more of this post

Using the BlockingCollection for thread-safe producer-consumer scenarios in .NET Part 5

In the previous post we finished the basics of building producer-consumer scenarios with BlockingCollection in .NET. In particular we saw how to send a signal to the consumer that the producers have completed their tasks and no more items will be inserted into the work queue.

In this final post I just want to draw your attention to a couple of other fine-tuning methods in the BlockingCollection object.

Read more of this post

Using the BlockingCollection for thread-safe producer-consumer scenarios in .NET Part 4

In the previous post we saw how to wire up the producer and the consumer in a very simplistic producer-consumer scenario in .NET using a BlockingCollection. We started a number of producer and consumer threads and checked their output in the Debug window.

In this post we’ll see how we can send a signal to the consumer that all producers finished adding new items to the work queue. This is to simulate a scenario where you can determine in advance when all expected items have been added to the work queue.

Read more of this post

Using the BlockingCollection for thread-safe producer-consumer scenarios in .NET Part 3

In the previous post of this mini-series we started building our model for the producer-consumer scenario. We have two objects to begin with. First, WorkTask.cs which represents the task that’s added to the work queue by the producers and retrieved by the consumers to act upon. Second we have an object, WorkQueue to encapsulate the work queue itself. It will be the consumer of the work queue through the MonitorWorkQueue method.

We haven’t yet seen the the consumer class yet. We’ll do that in this post.

Read more of this post

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: