Clone and Dispose Extension Methods for List(Of T)

Here are a couple more extension methods I wrote that I think will prove useful for other programmers. I have more… but many times an extension method is just a way to make programming more convenient or natural for ONE programmer (me, of course)… for example, I have a regular expression method that simulates the JavaScript method of testing a string against a regular expression, as that’s more comfortable for me… the .Net way isn’t as simple. I have some string extension methods for things I like to do as well… but these are just methods to help me program more efficiently the way I THINK. But then, some times, there are extension methods from which most programmers could benefit, and Clone and Dispose fall into this category.

Hopefully we’re all familiar with implementing IDisposable in a class to allow us to explicitly define what happens when we dispose an instance of that class. We don’t always need to do this but if we start dealing with unmanaged resources, this is a must! What about ICloneable? Hopefully we’re all familiar with this one as well and have used it to perform deep copies of user-defined reference types, where a dynamic copy would not otherwise be available. Implementing IDisposable provides the .Dispose() method and implementing ICloneable provides the .Clone method. I’ll leave any further education on these two interfaces up to you and assume you know if you need them and how to implement them.

So, ICloneable and IDisposable are interfaces you implement on a class, but how often do you deal in Generic Lists of these classes? I frequently need to dispose of the resources of each object in a generic list, and I frequently need to clone all the objects in a generic list. Typically, that involves writing a for each loop to spin through each element and either dispose the element or clone it and add it to a new list. This can happen quite frequently in some programs, so I write the Dispose and Clone extension methods that operate on the List(Of T) type… which means they are available any any generic list on any type! Here are the methods and I’ll follow them up with a usage:

VB:

        <Extension()> _
        Public Function Clone(Of T)(ByVal source As List(Of T)) As List(Of T)
            If source Is Nothing Then
                Return Nothing
            Else
                Dim out As New List(Of T)
                For Each x As T In source
                    If TypeOf x Is ICloneable Then
                        out.Add(DirectCast(DirectCast(x, ICloneable).Clone, T))
                    End If
                Next
                Return out
            End If
        End Function
        ''
        <Extension()> _
        Public Sub Dispose(Of T)(ByVal source As List(Of T))
            If source IsNot Nothing Then
                For Each x As T In source
                    If TypeOf x Is IDisposable Then
                        DirectCast(x, IDisposable).Dispose()
                    End If
                Next
            End If
        End Sub

C#:

        public static List<T> Clone<T>(List<T> source)
        {
            if (source == null) return null;
            else {
                List<T> dest = new List<T>();
                foreach (var x in source)
                    if (x is ICloneable) dest.Add((T)((ICloneable) x).Clone());
                return dest;
            }
        }
        //
        public static void Dispose<T>(List<T> source)
        {
            if (source != null)
            {
                foreach (var x in source)
                    if (x is IDisposable) ((IDisposable) x).Dispose();
            }
        }

The usage of these methods might look like this (C# only to save time):

            // string is a class that implements ICloneable and we'll pretend also IDisposable

            // setup
            List<string> strings = new List<string>();
            strings.Add("Rocky");
            strings.Add("Cherry");
            //
            // clone the list of strings
            List<string> clonedstrings = new List<string>();
            foreach (var s in strings)
            {
                clonedstrings.Add(s.Clone().ToString());
            }
            //
            // with extension method:
            List<string> clonedstrings = strings.Clone();
            //
            // now dispose of the strings, original list first:
            foreach (var s in strings)
                s.Dispose();
            //
            // with extension method:
            strings.Dispose();

It doesn’t save us a LOT of code, particularly on the dispose, but the one-line usage is nice. The extension method code is more self-documenting and considering we deal with very many lists using generic types, I can see the benefit in using these methods. I’m training now so I won’t have a chance to put these to use on any projects for a while so if anyone else does, I’d like to hear of it.

Rocky

About Rocky Cherry

I'm an Account Analyst/Trainer at Data-Tronics Corp, a Master of Management Information Sciences and Bachelor of Computer Sciences from Oklahoma State, a husband, dog owner, and motorcycle enthusiast...
This entry was posted in .Net, C#, Extension Methods, Interfaces, Visual Basic and tagged , , , , , , , , , . Bookmark the permalink.

Leave a Reply