July 2009 Archives

LINQBugging - Using LINQPad For WinForms Testing

| No TrackBacks

Did you know that you can use LINQPad to test your WinForms app while you're doing development, and easily ?  I don't think that this is a feature that's widely used (and in fact, I don't think that the author himself thought of that idea!  ::grins, hi Joe!::) while using LINQPad. 

So, how do you do it ?

Right click in your query window and select Advanced Properties.  On the Additional References tab select "Add" and then "Browse".  Find the assembly that you wish to test.  Also make sure you add any other necessary assemblies, and especially System.Windows.Forms.dll.  You'll then want to switch to the Additional Namespace Imports tab and type in the Namespace of your assembly that you wish to test, so that you'll have IntelliSense. 
Important Note:  Make sure you list your namespaces in the "most dependant ones last."  i.e., start with System.Windows.Forms so that you'll get proper IntelliSense.

Now, with something similar to the following code (make sure to switch the language to C# Program and put this in the Main {} method):

using(MyFormThatIWantToTest myForm = new MyFormThatIWantToTest()) {
  myForm.ShowInTaskbar = true;
  myForm.ShowDialog();
}

It's important to set your form to show in the taskbar because if you open it as a Dialog without, it will be very easy for you to lose you form.  The reason for opening it as a Dialog.. if you don't, the form will immediately close.

You can use this technique (I call it "LINQBugging") to test a lot of different scenarios and in some cases, save yourself a lot of time.  Why does this save you time ?  You can jump straight to your form/dialog without having to go through any unnecessary steps that you might otherwise if you launch your application directly, or from Visual Studio.  I use this technique all the time.  Couple this with Hawkeye to quickly prototype and test forms within your application and bypass the tedious navigation and security of your application to get there.

Also, make sure you open up your project in Visual Studio!  You can make changes and recompile your application and then execute (something similar to the above code) your LINQPad "Query" again.  One note, you need to close you form if you have it opened with LINQPad, otherwise the executable will become locked.  After that, once you make changes to your source code and recompile, LINQPad will execute the new code the next time you run the "query".

There are a lot of other things that you can do with this technique.. testing libraries, writing test procedures, etc.  Now that you know how to do this, what other tips and tricks do you have that I haven't thought of ?

* Note:  Yes, you can have a lot of fun with applications that aren't your own.. a little Reflector, and a little LINQPad can go a long way.  Don't abuse it. :)

Thanks for reading,

Matthew MacSuga

Reflection based IEnumerable<T> TrimAll() function

| No TrackBacks

Sorry for the too-long delay in updating my blog.  As usual, I’ve been pretty busy with a lot of things lately!! … you know, with the new job, summer activities, reading books.. stuff you probably don’t care a lot about. 

Today’s entry is going to deal with a pretty snazzy function I wrote as an Extension method called TrimAll().  This extension method is used when I’m gathering data from a database that has a lot of CHAR(x) fields in it and I’d rather not deal with space padding cluttering my code or UI’s.

/// <summary>
/// Dictionary that serves as a cache for cached PropertyInfo[] arrays
/// </summary>
static Dictionary<Type, PropertyInfo[]> trimCache;
/// <summary>
/// This function trims all public properties on an Enumerable object 
/// except those specified as optional parameters
/// </summary>
/// <typeparam name="T">The type of object</typeparam>
/// <param name="sourceList">A list of items</param>
/// <param name="ignoredFields">Props that should not be trimmed</param>
/// <returns>A cleaned up list with all string padding removed</returns>
public static List<T> TrimAll<T>(this IEnumerable<T> sourceList, 
params string[] ignoredFields)
{        
  if (trimCache == null)
    trimCache = new Dictionary<Type, PropertyInfo[]>();
 
  //  The list that we will be returning
  List<T> rList = new List<T>();
 
  //  Added for performance
  PropertyInfo[] props = null;
 
  //  Try to get a value from the dictionary if it exists
  if (!trimCache.TryGetValue(typeof(T), out props)) 
  {
    //  Get the properties for the type
    props = typeof(T)
              .GetProperties()
              .Where(c => !ignoredFields.Contains(c.Name) && 
                c.CanWrite && 
                c.PropertyType == typeof(System.String))
              .ToArray();
    //  Add it to the array
    trimCache.Add(typeof(T), props);
  }
 
  //  Iterate over each item in the source list
  foreach (T obj in sourceList) 
  {
    //  Iterate over each of the filtered properties
    for (int i = 0; i < props.Length; i++) 
    {
      //  Get the value 
      string o = (string)props[i].GetValue(obj, null);
      //  If it's not null, .Trim() it, otherwise leave it alone
      if (o != null)
        (props[i]).SetValue(obj, o.TrimEnd(
                                   ' ', 
                                   '\t', 
                                   '\n', 
                                   '\v', 
                                   '\f', 
                                   '\r'), null);
    }
 
    //  Add to the list
    rList.Add(obj);
  }
 
  //  Return the list!
  return rList;
}

 

So, there you have it.  I did do a bit of editing to make this fit within the constraints of my blog theme, but you should get the idea.

Explanation:

1.  I created a Dictionary of type Dictionary<Type,PropertyInfo[]> to improve performance of the TrimAll function on subsequent calls.  The first call will grab all of the public string properties of the input enumerable object and cache the reflection for future uses.

2.  When the function is called, it checks to see if the type of the current object <T> has already been entered into the cache.  For this, I use the TryGetValue object on the Dictionary class.  This is a very handy function that will return true/false if the Key is present in the dictionary.  In this case, the Type of the object is the key.  If the value is not present in the dictionary, then it will be created and added to the dictionary.

3.  You’ll notice that I’m using LINQ to search through all of the public properties of the source type.  I am also filtering the list if there are any optional string parameters passed in for properties that you would not want filtered.. as well as making sure that the property is writable, and that it is a string.

4.  Once the PropertyInfo[] props object is populated it is added to the cache for future use.

5.  With the new array of PropertyInfo objects for the source list, I start iterating over each object in the list.  For each object, I iterate over each item in the props[] array.  If the value is not null I update the Property in the object with a Trimmed version of the string.  You’ll notice that I am using “TrimEnd” with the specific fields I want to have trimmed explicitly specified.  I’m doing this to save a little bit of processing time and make the function slightly more efficient.  If you look at the TrimEnd method in Reflector, you’ll notice that it would cause several more iterations over each character.. this way I am saving those extra cycles.

6.  Finally, the updated object is added to the storage List<T> (rList) and returned to the calling function.

I hope you find this as useful as I have.. it’s saved me quite a few headaches and it’s nice having an easy way to Trim all of the values from my database in one fell swoop.

Usage:

using(…DataContext dc = new …DataContext()) {
  // With a Stored Procedure
  var dataList = dc.spSomeSproc().TrimAll();
  //
  var dataList2 = myTable.Where(c => c.SomeVal == “SearchVal”).TrimAll();
}


One of the nice features of this function is that it saves you the extra step of converting your returned Enumerable sequence to a List using .ToList().  I don’t know about you, but I quite often find myself doing that.  Of course, if your database is “normal” and isn’t full of CHAR fields (vs. VARCHAR) then you won’t have to worry about this at all. 

Knowing that most people probably don’t worry about CHAR fields, I still thought this made a nice blog post given that I am a huge fan of Reflection and finding neat ways to solve problems using it.  As usual, YMMV.

Question:  Do you think there is anyway to optimize this method further ?

Thanks for reading!

P.S.  You can now find me on Twitter.  Link:  http://www.twitter.com/csharpbydesign

Matthew MacSuga

About this Archive

This page is an archive of entries from July 2009 listed from newest to oldest.

February 2009 is the previous archive.

December 2011 is the next archive.

Find recent content on the main index or look in the archives to find all content.