Wednesday, May 19, 2010

Finally, A Pig-Latin Method for String!!

I was working on the NerdDinner tutorial and as I was using the intellisense, I noticed this icon: . I thought for a while that perhaps this downward arrow icon meant that the method was deprecated and that it was no longer to be used. I got really concerned, but later on in the tutorial I noticed that this meant the method was an "Extention method"! How did I miss this?!? This has been there since .NET 3.0! I know, that was back in my single days...I must have been thinking about how to ask out my wife.
If you are as clueless as I was, let me explain. This new feature allows any static class that is referenced in your project to add additional methods to any other class. Using the this operator on the first parameter of your static method lets the compiler know what object type you are extending. Immediately, I saw an incredible opportunity!
The string type has a lot of neat methods that can be used for parsing and formatting, but it lacks one glaringly obvious feature: a ToPigLatinEncryption() method!
Now using extension methods, we can make a static class called StringHelper. This class will have a static method called ToPigLatinEncryption that has a this operator on the first parameter. Behold, my custom written Pig-Latin Extension Method. Now that's some Pretty Good Privacy (PGP)! For the Pig-Latin Open Source Community:

public static class StringHelper
{
public static string ToPigLatinEncryption(this string ToEnrcypt)
{
string[] words = ToEnrcypt.Split(' '); //Split the sentence into words
StringBuilder pig = new StringBuilder();
foreach (string word in words)
{
if (word == "") //If empty string, there was an extra space.
{
pig.Append(" ");
}
else if (word.Length == 1) //Leave one letter words alone.
{
pig.AppendFormat("{0} ", word);
}
else
{
char[] b = word.ToCharArray();
bool upper = char.IsUpper(b[0]); //Is this word upper case
bool shth = (word.Substring(0, 2).ToLower() == "th"
|| word.Substring(0, 2).ToLower() == "sh"
|| word.Substring(0, 2).ToLower() == "wh"
|| word.Substring(0, 2).ToLower() == "qu"); //Any two sylyble sounds?
bool hasPunc = char.IsPunctuation(b[b.Length - 1]); //Any punctuation after the word. Only one allowed!
bool isWord = char.IsLetter(b[0]); //Is this a word?
string newPreSuffix = word.Substring(0, shth ? 2 : 1).ToLower(); //Get the first part of the word
string newPrefix = word.Substring(shth ? 2 : 1, word.Length - (shth ? 2 : 1)); //Get the last part of the word
if (upper) //If first part was uppercase, make the new first part uppercase
newPrefix = string.Format("{0}{1}", newPrefix.Substring(0, 1).ToUpper(), newPrefix.Substring(1));
string puncfix = string.Empty;
if (hasPunc)//If trailing punctation, deal with that.
{
puncfix = newPrefix.Substring(newPrefix.Length - 1, 1);
newPrefix = newPrefix.Substring(0, newPrefix.Length - 1);
}
pig.AppendFormat("{0}{1}ay{2} ", newPrefix, newPreSuffix, puncfix); //Write my new pig-latin word!!
}
}
return pig.ToString().Trim();
}

}

Now as long as that code is referenced in my project, I will be able to use it like any string method. It will even show up in my intellisense! Owhay oolcay siay atthay!