Create Mixins with Interfaces and Extension Methods
Bill Wagner (a MVP) has written a interesting article on how to create mixins with interfaces and extension mehods in C# 3.0. The ideas can easily be extended to VB.NET:
Mixins are small utility classes that define some useful functionality that will usually become part of something larger. For example, a class that implements a serial number to uniquely identify an object, or a timestamp that reports when an object was created. In C++, these mixin classes would be created using regular class definitions, and larger classes that wanted to use the mixin behavior would simply inherit from the mixin, in addition to any base classes it needed. Because the .NET Framework does not support multiple inheritance, we’ve typically used interface to define mixins. That works, but it’s not as powerful. One of the limitations of using interfaces to define mixin behavior is that every class that implements an interface must reimplement every method defined in that interface. That leads many developers to creating minimal interface definitions. (IEqualityComparer<T> has one method, IComparable<T> has only method). In those instances, the interface’s full functionality is completely defined in those small methods. But, what about cases where your interface can, or should, contain many more methods in order to support the developers that want to use the interface? That’s a perfect use case for extension methods. By creating extension methods using the interface, you can inject many more methods into the public definition of the interface, without forcing every developer to re-create those methods whenever he or she implements that interface. [...]
Published on Feb 15th, 2008 —
Tags: C# 3.0, extension methods
Comments (0)
digg it!
kick it
Extension Methods in C# 3.0
I have created a short screencast that introduces you with extension methods in C# 3.0.
In this webcast I explain why extension methods have been added to .NET 3.5. What are the benefits of using them? Then I’m going to show you how to create your own extension methods in C#. I also explain how the extension method calls are translated by the compiler. In the end I also show the problems that might come up when extension methods are used heavily in applications.
Click here to watch the screencast
Published on Dec 29th, 2007 —
Tags: .NET, C# 3.0, extension methods, screencast
Comments (1)
digg it!
kick it
Extension methods: Copy all files in a directory (recursive)
Extension methods are just so much fun. Somebody over at Channel 9 asked about a solution to copy all files from one directory to another. I first provided a solution that did it in C# 2.0. But why not create one that is nicer, done in C# 3.0 and uses extension methods? And that’s what I got:
{
// Copies all files from one directory to another.
public static void CopyTo(this DirectoryInfo source, string destDirectory, bool recursive)
{
if (source == null)
throw
if (destDirectory == null)
throw
// Compile the target.
DirectoryInfo target =
// If the source doesn’t exist, we have to throw an exception.
if (!source.Exists)
throw
// If the target doesn’t exist, we create it.
if (!target.Exists)
target.Create();
// Get all files and copy them over.
foreach (FileInfo file in source.GetFiles())
{
file.CopyTo(Path.Combine(target.FullName, file.Name), true);
}
// Return if no recursive call is required.
if (!recursive)
return;
// Do the same for all sub directories.
foreach (DirectoryInfo directory in source.GetDirectories())
{
CopyTo(directory, Path.Combine(target.FullName, directory.Name), recursive);
}
}
}
The usage is the following:
source.CopyTo(“C:\\users\\chris\\desktop_backup”, true);
Extension methods: I love you! ![]()
.GetLast(), .TryGetLast() and .GetFirst() for IList<T>
How often have you done the following?
// … some other random code
Foo last = myListOfFoos[myListOfFoos.Count - 1];
It’s always a pain to re-type the variable name, get the count and substract one to get the last item in the list. It’s also a possible source of errors because you could accidentally mistype the variable name (you may have a variable with a very similar name that is also a list; intellisense helps very much there) or you could omit the -1, who knows. It’s always best to remove error sources, isn’t it?
Wouldn’t it be nice to use it like that:
// … some other random code
Foo last = myListOfFoos.GetLast();
Now with C# 3.5 and extension methods there is a way to get the second way working.
We only need to implement an extension method that gets the last element once and can use it from then on. I have decided to implement it for the IList<T> interface. That means that all classes that implement that interface provide that extension method.
We have only one problem now: an empty list throws an exception, if the method that gets the last item is called. To avoid that problem problem I have implemented a method that tries to get the last item. The method returns true, if the item could be fetched. The behaviour is the same as TryGetValue on Dictionary<TKey, TValue>:
{
// Gets the last item in the list.
public static T GetLast<T>(this IList<T> value)
{
if (value == null)
throw
return value[value.Count - 1];
}
// Tries to get the last item in the list.
public static bool TryGetLast<T>(this IList<T> value, out T result)
{
if (value == null)
throw
if (value.Count == 0)
{
result = default(T);
return false;
}
result = GetLast<T>(value);
return true;
}
// Gets the first item in the list.
public static T GetFirst<T>(this IList<T> value)
{
if (value == null)
throw
return value[0];
}
}
Annotations: tagging .NET objects
Extension methods in C# 3.0 are a great thing! Alex Henderson (from New Zealand) has build a small library for C# 3.0 that allows to annotate (or tag) objects.
{
ClassA target1 =
ClassA target2 =
ClassA target3 =
// Tag some objects.
target1.Annotate(Description => “class number 1″);
target2.Annotate(Description => “class number 2″);
target3.Annotate(Parsed => true);
// Get the objects with the given key.
var results = AnnotationStore.Classes
.Where(a => a.HasKey(“Description”))
.ToList();
Assert.AreEqual(2, results.Count);
}
This library is a very interesting and creative way to use extension methods in C# 3.0. I wonder what other creative ideas are going to come up that are using extension methods.
Published on Jul 4th, 2007 —
Tags: .NET, C# 3.0, extension methods, Tagging objects
Comments (0)
digg it!
kick it
Sample: Encrypt and compress in .NET
Channel 9 is a source of inspiration with all the questions that are asked. Today in a second post somebody asked about a problem in his compression and encryption code. I looked at the code and thought why not to create an own utility class that compresses/decompresses and encrypts/decrypts a piece of data.
That’s what I got (the comments make the code very much self explaining):
{
/// <summary>
/// Encrypts and compresses the input. Returns the compressed and encrypted content and the key and iv vector used.
/// </summary>
/// <param name="input">The input array.</param>
/// <param name="key">The key that has been used by the algorithm.</param>
/// <param name="iv">The iv vector that has been used by the algorithm.</param>
/// <returns></returns>
public static byte[] EncryptAndCompress(byte[] input, out byte[] key, out byte[] iv)
{
if (input == null)
throw
// Compress the input array into the given memory stream.
MemoryStream stream =
using (GZipStream zip =
{
// Write the input to the memory stream via the ZIP stream.
zip.Write(input, 0, input.Length);
}
// Create the keys and initalize the rijndael.
RijndaelManaged r =
r.GenerateKey();
r.GenerateIV();
// Set the generated key and iv vector.
key = r.Key;
iv = r.IV;
// Encrypt the compressed memory stream into the encrypted memory stream.
MemoryStream encrypted =
using (CryptoStream cryptor =
{
// Write the stream to the encrypted memory stream.
cryptor.Write(stream.ToArray(), 0, (int)stream.Length);
cryptor.FlushFinalBlock();
// Return the result.
return encrypted.ToArray();
}
}
/// <summary>
/// Decrypts and decompresses the input. Returns the decompressed and decrypted content.
/// </summary>
/// <param name="input">The input array.</param>
/// <param name="key">The key used for decrypt.</param>
/// <param name="iv">The iv vector used for decrypt.</param>
/// <returns></returns>
public static byte[] DecryptAndDecompress(byte[] input, byte[] key, byte[] iv)
{
if (input == null)
throw
if (key == null)
throw
if (iv == null)
throw
// Initialize the rijndael
RijndaelManaged r =
// Create the array that holds the result.
byte[] decrypted =
// Create the crypto stream that is used for decrypt. The first argument holds the input as memory stream.
using (CryptoStream decryptor =
{
// Read the encrypted values into the decrypted stream. Decrypts the content.
decryptor.Read(decrypted, 0, decrypted.Length);
}
// Create the zip stream to decompress.
using(GZipStream zip =
{
// Read all bytes in the zip stream and return them.
return ReadAllBytes(zip);
}
}
/// <summary>
/// Reads all bytes in the given zip stream and returns them.
/// </summary>
/// <param name="zip">The zip stream that is processed.</param>
/// <returns></returns>
private static byte[] ReadAllBytes(GZipStream zip)
{
if (zip == null)
throw
int buffersize = 100;
byte[] buffer =
int offset = 0, read = 0, size = 0;
do
{
// If the buffer doesn’t offer enough space left create a new array
// with the double size. Copy the current buffer content to that array
// and use that as new buffer.
if (buffer.Length < size + buffersize)
{
byte[] tmp =
Array.Copy(buffer, tmp, buffer.Length);
buffer = tmp;
}
// Read the net chunk of data.
read = zip.Read(buffer, offset, buffersize);
// Increment offset and read size.
offset += buffersize;
size += read;
} while (read == buffersize); // Terminate if we read less then the buffer size.
// Copy only that amount of data to the result that has actually been read!
byte[] result =
Array.Copy(buffer, result, size);
return result;
}
}
It can be used like in the following example:
byte[] iv = null;
byte[] input = File.ReadAllBytes(“C:\\Users\\Chris\\Documents\\UNI\\Untitled.bmp”);
byte[] result = EncryptAndCompressUtility.EncryptAndCompress(input, out key, out iv);
File.WriteAllBytes(“C:\\Users\\Chris\\Documents\\UNI\\foo compressed.bmp”, result);
byte[] result2 = EncryptAndCompressUtility.DecryptAndDecompress(File.ReadAllBytes(“C:\\Users\\Chris\\Documents\\UNI\\foo compressed.bmp”), key, iv);
File.WriteAllBytes(“C:\\Users\\Chris\\Documents\\UNI\\foo.bmp”, result2);
Get all files in a directory and sub directories by extension(s)
A post over at Channel 9 inspired me to create a simple class to do directory listing by extensions. The problem guy’s problem was that he could only use one extension when doing a file listing of a directory. My new class allows to search for multiple file extensions in one run:
{
/// <summary>
/// Gets the files by the given extensions from the given path.
/// </summary>
public static string[] GetFilesByExtensions(string path, string extensions, SearchOption option)
{
List<string> result =
InternalGetFiles(path, option, extensions.Split(‘;’), result);
return result.ToArray();
}
private static void InternalGetFiles(string path, SearchOption option, string[] extensions, List<string> result)
{
// Get the files.
string[] files = Directory.GetFiles(path);
foreach (string file in files)
{
// Get the extension of the file.
string ext = Path.GetExtension(file);
// Validate the extension against the searched extensions.
foreach (string p in extensions)
{
if (ext == p)
{
result.Add(file);
break;
}
}
}
// Returns if only top directory is requested.
if (option == SearchOption.TopDirectoryOnly)
return;
// Get all other directories.
foreach (string directory in Directory.GetDirectories(path))
{
InternalGetFiles(directory, option, extensions, result);
}
}
}
I’m using a List<string> (as temporary container for the found files) in this example, because it makes it easy to add new results to it. A list is a smart array, which doubles the internal array’s size (and copies the current items to the new array) when the internal array is full.
Usage would look like this:
“C:\\Users\\Chris\\Documents\\“, “.txt;.docx;.doc”,
SearchOption.AllDirectories);
Making DataReaders play nicely with LINQ
Ever thought of using ADO.NET in combination with Linq? I mean not to create the query, but to actually filter the results returned by the database? Alex James (from base4.net) is showing us some great examples on how ADO.NET, Linq and extension methods play nicely together. Check it out.
… and I agree with him that C# 3.0 (or is it C# 3.5?) is great! ![]()





