Miscellaneous Utilities Tutorial

This tutorial aims to teach you about the existence of and how to use a few small utility methods that add strangely missing functionality to .NET's Base Class Library. It assumes you already know C#. All the classes and methods referred to herein belong to the DigitallyCreated.Utilities.Bcl library.

Collection AddAll/RemoveAll

Strangely, the ICollection<T> interface does not provide AddAll and RemoveAll methods, which makes adding or removing collections of objects from a collection painful (1 line of code painful, but still!). The Extensions.AddAll and Extensions.RemoveAll extension methods add this functionality to ICollection<T>.

IList<int> list = new List<int> { 1,2,3,4,5 };
IList<int> list2 = new List<int> { 6,7,8,9,10 };
list.AddAll(list2);

IEnumerable<int> enumerable = new List<int> { 2, 4 };
list.RemoveAll(enumerable);

Case Insensitive String Comparison

Case insensitive string comparison is awkward in .NET, making you do this contortion:

bool areEqual = String.Compare(firstString, compareToString, true) == 0;

Now you can use the Extensions.EqualsIgnoreCase extension method to make this a little nicer and more natural:

bool areEqual = firstString.EqualsIgnoreCase(compareToString);

Base64StreamReader

Sometimes you've got some Base64 encoded data and you want to read it like a stream. This is especially useful when reading from a large Base64 encoded data source (like a file, or a network stream) and then saving the decoded output bytes into a file on disk without loading the whole lot into memory at once.

Here's a contrived example of the Base64StreamReader in action where we encode some random data into Base64 then decode it using the Base64StreamReader:

void Main()
{
    //Create random data and encode to Base64
    Random random = new Random();
    byte[] originalBytes = new byte[256];
    random.NextBytes(originalBytes);
    string base64Str = Convert.ToBase64String(originalBytes, Base64FormattingOptions.InsertLineBreaks);

    //Create the streams
    StringReader strReader = new StringReader(base64Str);
    Base64StreamReader reader = new Base64StreamReader(strReader);
    
    //Read and decode from Base64Stream into readBytes
    byte[] readBytes = new byte[originalBytes.Length];
    int offset = 0;
    int read;
    while ((read = reader.Read(readBytes, offset, Math.Min(32, originalBytes.Length - offset))) > 0)
    {
        offset += read;
    }
}

Note that Base64StreamReader does not support writing to the stream or seeking around the stream, only reading.

Useful Common Exception Types

The Bcl library contains some exception types for errors that you encounter fairly often but the .NET BCL contains no exception type for.

AggregateException

An AggregateException is a type of exception that allows you to bundle up multiple exceptions and throw them together. A place where you might want to do this is where you encounter an exception when cleaning up after an exception, like so:

try
{
    DoSomeStuff();
}
catch (Exception e)
{
    try 
    {
        BackOut();
    }
    catch (Exception e2)
    {
        throw new AggregateException(e, e2);
    }
	
    throw;
}

Note that AggregateException has been added to the official .NET BCL in .NET 4.0, so it is likely that the DigitallyCreated Utilities version will be obsoleted when the project shifts to .NET 4.0.

IllegalStateException

The IllegalStateException is good to throw when an object has gotten into an illegal state.

NotFoundException

The NotFoundException is good to throw when some data entity is missing. It allows you to set an entity name and ID, and therefore is useful for error handling code that can display this back to the user in a friendly way.

throw new NotFoundException("Customer", customerId.ToString());

Last edited Mar 5, 2010 at 5:03 AM by dchambers, version 3

Comments

No comments yet.