Obviously, there are many reasons for overriding the default LINQ operator behavior. However, the most interesting use of extension methods for LINQ isn’t in overriding the operators. You can also use extension methods to override standard .NET Framework classes, such as String. When you combine extension methods with LINQ, it’s possible to create new methods for standard .NET Framework classes that perform special tasks in an elegant way. Listing 3 shows an extension method for the String class the lets you count special characters in a string.
ADVERTISEMENT
Listing 3: Creating an Extension Method with LINQ
public static class MyStrings
{
public static int SpecialCharCount(this String Str)
{
// Define a LINQ Query for special characters.
var CharQuery = from ThisCount
in Str
where ThisCount == '!'
|| ThisCount == '@'
|| ThisCount == ';'
|| ThisCount == ','
|| ThisCount == ':'
|| ThisCount == '?'
|| ThisCount == '+'
|| ThisCount == ' '
select ThisCount;
// Return the number of special characters.
return CharQuery.Count<Char>();
}
}
In this case, two lines of code are all you need to perform the task. The first line is a LINQ query that tells the compiler to review the input string one character at a time. Whenever the character matches any of the where criteria, the query should select that character and place it in the output enumeration, CharQuery. Notice that this query contains multiple where cases and that it relies on the || (or) operator. You can add as many entries as needed to capture all the special characters without spending a lot of time writing switch statements and special looping code.
The second line is equally simple. The code relies on the Count<of T> method to count the number of Char type entries in CharQuery. The result is the number of special characters. You can use the code shown in Listing 4 to test this extension.
Listing 4: Testing the LINQ-based Extension
private void btnTest_Click(object sender, EventArgs e)
{
// Define a string with special characters.
String MyString = "abcd;@abc,abc:abc?abc+ hello!";
// Obtain the number of special characters.
int CharCount = MyString.SpecialCharCount();
// Display the result.
txtResult.Text =
"The number of special characters is: " +
CharCount.ToString();
}
The code begins by creating a nonsense string with special characters. Because this is an extension method, you can access the SpecialCharCount() method as if it were part of the String type. The output of the call is an int value that tells you how many special characters the string contains. The final step outputs this value to txtResult.Text.
It pays to think about the order in which you add filters to a query. As shown in Figure Listing 3, you can end up with a significant list of checks for a given query. By placing the characters (or other checks) that you expect to succeed most often at the top of the list, you reduce the number of comparisons that LINQ performs and improve application performance.
Bottom Line
Extension methods spell flexibility for the LINQ developer. Not only do extension methods provide a means for extending LINQ itself, you can also combine LINQ and extension methods to create new methods for existing .NET Framework classes. It’s not too hard to imagine that the results of these combinations are going to translate into functionality that even Microsoft never imagined. You can combine LINQ and extension methods to create as many new language features as needed to answer any programming need.
BIO
John Mueller is a freelance author and technical editor. He has writing in his blood, having produced 79 books and over 300 articles to date. The topics range from networking to artificial intelligence and from database management to heads down programming. His current project is LINQ for Dummies (scheduled for publication in August 2008), which you can preorder at http://www.amazon.com/exec/obidos/ASIN/0470277947/datacservip0f-20/. His technical editing skills have helped over 56 authors refine the content of their manuscripts. You can reach John on the Internet at JMueller@mwt.net and his Web site at: http://www.mwt.net/~jmueller/.