C# 3.0 Features: Extension Methods

.NET 3.5 is out which means all of the great features available in C# 3.0 are available to use now.  Here's a quick list of the main language enhancements available in C# 3.0:

  • Object Initializers
  • Automatic Properties
  • Extension Methods
  • Anonymous Types
  • Lambda Expressions
  • LINQ
  • Collection Initializers

    Extension methods allow existing classes to be extended without relying on inheritance or having to change the class's source code.  This means that if you want to add some methods into the existing String class you can do it quite easily.  Here's a couple of rules to consider when deciding on whether or not to use extension methods:

    • Extension methods cannot be used to override existing methods

    • An extension method with the same name and signature as an instance method will not be called

    • The concept of extension methods cannot be applied to fields, properties or events

    • Use extension methods sparingly....overuse can be a bad thing!

    Here's an example of creating an extension method in C# that adds a RemoveNonNumeric() method to the String class.  Notice that the class is defined as static as well as the extension method itself.  The "this" keyword in the parameter signature tells the compiler to add the extension method to the String class since "string" follows the keyword.

    namespace StringExtensions
    {
        public static class StringExtensionsClass
        {
            public static string RemoveNonNumeric(this string s)
            {
                MatchCollection col = Regex.Matches(s, "[0-9]");
                StringBuilder sb = new StringBuilder();
                foreach (Match m in col)
                    sb.Append(m.Value); 
                return sb.ToString();
            }
        }


    Here's an example of how the extension method can be used.  You'll see that the namespace for the extension method class is imported.  From there, the compiler treats the RemoveNonNumeric() method as if it was originally part of the standard System.String class. 

    using StringExtensions;
    


    .... string phone = "123-123-1234"; string newPhone = phone.RemoveNonNumeric();

     

    Update:  Although the overall point of the post was to simply show how to create extension methods, Andrex posted a more efficient way to remove non-numeric characters for those that may actually need that specific functionality (I'll admit I was just throwing something out there :-)).  Thanks for commenting Andrex!

    public static string RemoveNonNumeric(this string s)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.Length; i++)
            if (Char.IsNumber(s[i]))
                sb.Append(s[i]);
        return sb.ToString();
    }


  • Update 2:  Richard posted the following method which is potentially even faster according to his tests.  We're kind of pulling hairs here, but it's useful for "anyone who agonizes over every wasted millisecond" as he mentions in the comments (I'm not one of those people :-)).  I'm thinking I should start a "How would you refactor this code" series.  Could be kind of fun.  :-)

    public static string RemoveNonNumeric(this string s)
    {
        if (!string.IsNullOrEmpty(s))
        {
            char[] result = new char[s.Length];
            int resultIndex = 0;
            foreach (char c in s)
            {
                if (char.IsNumber(c))
                    result[resultIndex++] = c;
            }
            if (0 == resultIndex)
                s = string.Empty;
            else if (result.Length != resultIndex)
                s = new string(result, 0, resultIndex);
        }
        return s;
    }

     

    del.icio.us Tags: ,

    Published Friday, January 25, 2008 1:15 PM by dwahlin

    Comments

    # re: C# 3.0 Features: Extension Methods

    Friday, January 25, 2008 4:50 PM by rrobbins

    I just wrote a string extension method to chop off characters from the end of a string. I often need this to remove a trailing comma from a comma seperated list I created dynamically.

    # re: C# 3.0 Features: Extension Methods

    Friday, January 25, 2008 5:46 PM by andrex

    I think that the use of regular expressions for such simple tasks not the best solution. I suggest that his version:

    public static string RemoveNonNumeric2(this string s)

    {

     StringBuilder sb = new StringBuilder();

     for (int i = 0; i < s.Length; i++)

       if(Char.IsNumber(s[i]))

         sb.Append(s[i]);

     return sb.ToString();

    }

    I compared the time of the testing in a million iterations. The average execution time of your code about 6 sec 47 ms. My version - 0 sec 45 ms.

    # re: C# 3.0 Features: Extension Methods

    Friday, January 25, 2008 8:24 PM by dwahlin

    Andrex,

    Thanks for posting that.  It's certainly another viable way to filter characters.

    # re: C# 3.0 Features: Extension Methods

    Monday, January 28, 2008 3:19 PM by Richard

    Even more efficient:

    public static string RemoveNonNumeric3(this string s)

    {

       if (!string.IsNullOrEmpty(s))

       {

           char[] result = new char[s.Length];

           int resultIndex = 0;

           foreach (char c in s)

           {

               if (char.IsNumber(c))

               {

                   result[resultIndex++] = c;

               }

           }

           if (0 == resultIndex)

           {

               s = string.Empty;

           }

           else if (result.Length != resultIndex)

           {

               s = new string(result, 0, resultIndex);

           }

       }

       return s;

    }

    On my PC, andrex's method took 433ms, mine took 277ms. It's not really enough to worry about, but it might be handy for anyone who agonizes over every wasted millisecond!

    # &#8230;.::: VOX POPULI :::&#8230;. &raquo; Blog Archive &raquo; Extension Methods vs. Prototype

    Pingback from  &#8230;.:::   VOX POPULI   :::&#8230;.  &raquo; Blog Archive   &raquo; Extension Methods vs. Prototype

    # Extension Methods em C# &rsaquo; Miguel Alho - Multimédia

    Thursday, February 19, 2009 6:15 AM by Extension Methods em C# › Miguel Alho - Multimédia

    Pingback from  Extension Methods em C# &rsaquo;  Miguel Alho - Multimédia

    # Bambit Technologies: C# Extension Methods and log4net

    Wednesday, July 22, 2009 5:02 PM by Bambit Technologies: C# Extension Methods and log4net

    Pingback from  Bambit Technologies: C# Extension Methods and log4net

    # C# Extension Methods and log4net

    Saturday, October 24, 2009 9:24 PM by Name of the blog

    C# Extension Methods and log4net