MSBuild Community Task Collaboration Project

I’d like to announce the MSBuild Community Task Collaboration Project. The project was started by me to form a directory of MSBuild Tasks for use in your build scripts. The project is also an open source collection of tasks. The project is broke into 2 web sites.

The first is http://msbuildtasks.com/ which is a community server install with forums and a directory of MSBuild tasks. The goal of msbuildtasks.com is to provide a common place to find tasks. Please help improve this directory by adding links to tasks that you know about.


Generics at Runtime

Here is a little test code that demonstrates how to use Generics at runtime. The code has two tests. The first test shows how to create a Generic Class at runtime. The second shows how to call a Generic method. Keep in mind that when using generics at runtime, there will be a reflection performance hit.

using System;  
using System.Collections.ObjectModel;  
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;  
using System.Reflection;  
using System.Diagnostics;  
  
namespace GenericTest  
{  
    [TestClass]  
    public class GenericTest  
    {  
        [TestMethod]  
        public void CreateGenericAtRuntime()  
        {  
            Stopwatch watch = Stopwatch.StartNew();  
            // define the generic class at runtime  
            Type genericType = typeof(Collection<>).MakeGenericType(typeof(DateTime));  
            // create an instance of the generic type  
            object instance = Activator.CreateInstance(genericType);  
            watch.Stop();  
  
            Console.WriteLine("Dynamic Create Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
  
            Assert.IsNotNull(instance, "instance is Null");  
            Assert.IsTrue(instance is Collection<DateTime>);  
  
            Collection<DateTime> dates = instance as Collection<DateTime>;  
  
            Assert.IsNotNull(dates, "dates is Null");  
  
            watch = Stopwatch.StartNew();  
            Collection<DateTime> d = new Collection<DateTime>();  
            watch.Stop();  
  
            Console.WriteLine("Normal Create Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
        }  
  
        public Collection<T> GetCollection<T>()  
        {   
            return new Collection<T>();   
        }  
  
        [TestMethod()]  
        public void CallGenericMethodAtRuntime()  
        {  
            Stopwatch watch = Stopwatch.StartNew();  
            MethodInfo methodInfo = typeof(GenericTest).GetMethod("GetCollection");  
            MethodInfo genericInfo = methodInfo.MakeGenericMethod(typeof(DateTime));  
              
            object instance = genericInfo.Invoke(this, null);  
            watch.Stop();  
  
            Console.WriteLine("Dynamic Invoke Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
  
            Assert.IsNotNull(instance, "instance is Null");  
            Assert.IsTrue(instance is Collection<DateTime>);  
  
            Collection<DateTime> dates = instance as Collection<DateTime>;  
  
            Assert.IsNotNull(dates, "dates is Null");  
  
            watch = Stopwatch.StartNew();  
            Collection<DateTime> d = this.GetCollection<DateTime>();  
            watch.Stop();  
  
            Console.WriteLine("Normal Invoke Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
        }  
    }  
}

Google Toolbar Spell Check API

I saw in this post that the Google toolbar could be extracted and looked at. So, I spend an afternoon reverse engineering the spell checker api. The api ends up to be very easy to use. Checking is done with an HTTP post to https://www.google.com/tbproxy/spell?lang=en&hl=en.

The xml structure looks like this…

<?xml version="1.0" encoding="utf-8" ?>
<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">
    <text>Ths is a tst</text>
</spellrequest>

The response look like …

<?xml version="1.0" encoding="UTF-8"?>
<spellresult error="0" clipped="0" charschecked="12">
    <c o="0" l="3" s="1">This Th's Thus Th HS</c>
    <c o="9" l="3" s="1">test tat ST St st</c>
</spellresult>
TagDescription
oThe offset from the start of the text of the word
lLength of misspelled word
sConfidence of the suggestion
textTab delimited list of suggestions

I created a complete C# GoogleSpell library as a demo. The library can be download at http://www.loresoft.com/files/uploads/GoogleSpell.zip


Stopwatch class from .net 2.0 framework ported .net 1.1

Here is the handy Stopwatch class from .net 2.0 framework back ported .net 1.1. Enjoy…

/// <summary>Provides a set of methods and properties that you can use to accurately measure elapsed time.</summary>  
public class Stopwatch  
{  
    #region SafeNativeMethods  
    [DllImport("kernel32.dll")]  
    private static extern bool QueryPerformanceFrequency(out long lpFrequency);  
    [DllImport("kernel32.dll")]  
    private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);  
    #endregion //SafeNativeMethods  
    #region Public Fields          
    /// <summary>Gets the frequency of the timer as the number of ticks per second. This field is read-only.</summary>  
    public static readonly long Frequency;  
      
    /// <summary>Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.</summary>  
    public static readonly bool IsHighResolution;  
     
    #endregion //Public Fields  
     
    #region Private Fields  
    private long elapsed;          
    private bool isRunning;  
    private long startTimeStamp;  
      
    private static readonly double tickFrequency;  
    #endregion //Private Fields  
    #region Constructors  
    static Stopwatch()  
    {  
        if (!QueryPerformanceFrequency(out Stopwatch.Frequency))  
        {  
            Stopwatch.IsHighResolution = false;  
            Stopwatch.Frequency = TimeSpan.TicksPerSecond;  
            Stopwatch.tickFrequency = 1;  
        }  
        else  
        {  
            Stopwatch.IsHighResolution = true;  
            Stopwatch.tickFrequency = TimeSpan.TicksPerSecond;  
            Stopwatch.tickFrequency /= ((double)Stopwatch.Frequency);  
        }  
    }  
      
    /// <summary>Initializes a new instance of the Stopwatch class.</summary>  
    public Stopwatch()  
    {  
        this.Reset();  
    }  
    #endregion //Constructors  
     
    #region Private Methods  
    private long GetElapsedDateTimeTicks()  
    {  
        long ticks = this.GetRawElapsedTicks();  
        if (Stopwatch.IsHighResolution)  
        {  
            double highTicks = ticks;  
            highTicks *= Stopwatch.tickFrequency;  
            return (long)highTicks;  
        }  
        return ticks;  
    }  
    private long GetRawElapsedTicks()
    {  
        long elapsedTimestamp = this.elapsed;  
        if (this.isRunning)  
        {  
            long currentTimestamp = Stopwatch.GetTimestamp();  
            long endTimestamp = currentTimestamp - this.startTimeStamp;  
            elapsedTimestamp += endTimestamp;  
        }  
        return elapsedTimestamp;  
    }  
    #endregion //Private Methods  
    #region Public Methods  
    /// <summary>Gets the current number of ticks in the timer mechanism.</summary>  
    /// <returns>A long integer representing the tick counter value of the underlying timer mechanism.</returns>  
    public static long GetTimestamp()
    {  
        if (Stopwatch.IsHighResolution)  
        {  
            long ticks = 0;  
            QueryPerformanceCounter(out ticks);  
            return ticks;  
        }  
        return DateTime.UtcNow.Ticks;  
    }  
    /// <summary>Stops time interval measurement and resets the elapsed time to zero.</summary>  
    public void Reset()
    {  
        this.elapsed = 0;  
        this.isRunning = false;  
        this.startTimeStamp = 0;  
    }  
    /// <summary>Starts, or resumes, measuring elapsed time for an interval.</summary>  
    public void Start()
    {  
        if (!this.isRunning)  
        {  
            this.startTimeStamp = Stopwatch.GetTimestamp();  
            this.isRunning = true;  
        }  
    }  
    /// <summary>Initializes a new Stopwatch instance, sets the elapsed time property to zero, and starts measuring elapsed time.</summary>  
    /// <returns>A Stopwatch that has just begun measuring elapsed time.</returns>  
    public static Stopwatch StartNew()
    {  
        Stopwatch stopwatch = new Stopwatch();  
        stopwatch.Start();  
        return stopwatch;  
    }  
    /// <summary>Stops measuring elapsed time for an interval.</summary>  
    public void Stop()
    {  
        if (this.isRunning)  
        {  
            long currentTimestamp = Stopwatch.GetTimestamp();  
            long endTimestamp = currentTimestamp - this.startTimeStamp;  
            this.elapsed += endTimestamp;  
            this.isRunning = false;  
        }  
    }  
    #endregion //Public Methods  
     
    #region Public Properties  
    /// <summary>Gets the total elapsed time measured by the current instance.</summary>  
    /// <value>A read-only System.TimeSpan representing the total elapsed time measured by the current instance.</value>  
    public TimeSpan Elapsed  
    {  
        get { return new TimeSpan(this.GetElapsedDateTimeTicks()); }  
    }  
      
    /// <summary>Gets the total elapsed time measured by the current instance, in milliseconds.</summary>  
    public long ElapsedMilliseconds  
    {  
        get { return (this.GetElapsedDateTimeTicks() / TimeSpan.TicksPerMillisecond); }  
    }  
    /// <summary>Gets the total elapsed time measured by the current instance, in timer ticks.</summary>  
    public long ElapsedTicks  
    {  
        get { return this.GetRawElapsedTicks(); }  
    }  
      
    /// <summary>Gets a value indicating whether the Stopwatch timer is running.</summary>  
    public bool IsRunning  
    {  
        get { return this.isRunning; }  
    }  
    #endregion //Public Properties  
}

Code Snippet to Convert Word Tense

Here is a useful code snippet to convert the tense of a word from single to plural and vise versa. The code uses a series of regular expression to examine the word and convert it using the correct grammar.

public string MakePlural(string name)  
{  
    Regex plural1 = new Regex("(?<keep>[^aeiou])y$");  
    Regex plural2 = new Regex("(?<keep>[aeiou]y)$");  
    Regex plural3 = new Regex("(?<keep>[sxzh])$");  
    Regex plural4 = new Regex("(?<keep>[^sxzhy])$");  
  
    if(plural1.IsMatch(name))  
        return plural1.Replace(name, "${keep}ies");  
    else if(plural2.IsMatch(name))  
        return plural2.Replace(name, "${keep}s");  
    else if(plural3.IsMatch(name))  
        return plural3.Replace(name, "${keep}es");  
    else if(plural4.IsMatch(name))  
        return plural4.Replace(name, "${keep}s");  
  
    return name;  
}  
  
public string MakeSingle(string name)  
{  
    Regex single1 = new Regex("(?<keep>[^aeiou])ies$");  
    Regex single2 = new Regex("(?<keep>[aeiou]y)s$");  
    Regex single3 = new Regex("(?<keep>[sxzh])es$");  
    Regex single4 = new Regex("(?<keep>[^sxzhy])s$");  
  
    if(single1.IsMatch(name))  
        return single1.Replace(name, "${keep}y");  
    else if(single2.IsMatch(name))  
        return single2.Replace(name, "${keep}");  
    else if(single3.IsMatch(name))  
        return single3.Replace(name, "${keep}");  
    else if(single4.IsMatch(name))  
        return single4.Replace(name, "${keep}");  
  
    return name;  
}