June 2008 Entries

It seems that enums might be the neglected step-child when it comes to Generics and Extensions.  I've tried defining generics that are constrained to enums.  No luck.  I faced much frustration trying to get my generic methods to work.  I finally came up with a method that meets my need.  But, I had to add a little bit of run-time type checking.

Instead of repeating Enum.Parse throughout my code, I wanted to create a simple generic extension method that would do it for me.

I just discovered that my extension is practically identical to Kirill Osenkov'sCheck out his discussion here.

   1: public static TResult ConvertTo<TResult>( this string source )
   2: {
   3:     if( !typeof(TResult).IsEnum )
   4:     {
   5:         throw new NotSupportedException( "TResult must be an Enum" );
   6:     }
   7:     return (TResult)Enum.Parse( typeof(TResult), source );
   8: }

If the compile time constraint were allowed, I would prefer this

   1: public static TResult ConvertTo<TResult>( this string source ) where TResult : Enum
   2: {
   3:     return (TResult)Enum.Parse( typeof(TResult), source );
   4: }

The usage is something like this.

   1: MyObject.ClosingStatus = input.ConvertTo<ClosingStatus>();
   2: //or
   3: reader.GetString( 2 ).ConvertTo<ClosingStatus>();

After I came up with this, I searched to find out if anyone else out there found a better way to resolve the limitations surrounding enums.  I found Christopher Bennage's post on Enum<T> and I like it quite a bit.

So, I've settled on a pattern that I found somewhere on the web to safely override Equals.  I don't remember where I found it, and there are certainly many other good implementations (probably better than mine).

Regardless, I found that I do have a repeating pattern.  I decided to set out to limit this duplication if I could.  Here is what I came up with.

   1: public static bool SafeEquals<T>( this T left, object right, Predicate<T> test )
   2: {
   3:     if( right != null && right.GetType().Equals( left.GetType() ) )
   4:     {
   5:         return test( (T)right );
   6:     }
   7:     return false;
   8: }

This is meant as a utility extension to help me override Equals in my classes without having to write that if condition over and over again.  Also, it takes care of casting to my type as well.

Here is an example of how it is used.  Suppose you have a class that should demonstrate equality if the Key property is equal:

   1: public override bool Equals( object obj )
   2: {
   3:     return this.SafeEquals( obj, test => test.Key == this.Key );
   4: }

or

   1: public override bool Equals( object obj )
   2: {
   3:     return this.SafeEquals( obj, test => object.Equals( test.Key, this.Key ) );
   4: }

Let me know what you guys think.

The string.Join method can come in handy when you want a comma separated list of strings.  However, there's a major limitation.  To use it, you must provide a one-dimensional string array.  What if you have a collection of objects and you want to "Join" a property on the objects (e.g., a comma separated list of IDs).

Well, since I couldn't find anything within the framework that would do this for me, I wrote an extension method that meets my need.

Updated from James Curran's suggestion in the comments. 

   1: public static string Join<T>( this IEnumerable<T> target, Func<T, object> valueSelector )
   2: {
   3:     StringBuilder result = new StringBuilder();
   4:     foreach( T item in target )
   5:     {
   6:         result.Append( valueSelector( item ).ToString() );
   7:         result.Append( "," );
   8:     }
   9:     result.Length--;
  10:     //remove the trailing comma    
  11:     return result.ToString();
  12: }

This will take any Generic Enumerable and Join the string representation based on the value selector you provide.

Here is an example of how to use it:

   1: public class Child
   2: {
   3:     public int Id { get; set; }    
   4:     public string Name { get; set; }    
   5:     // ...
   6: }
   7: public class Parent
   8: {
   9:     public int Id { get; set; }
  10:     public string Name { get; set; }
  11:     public List<Child> Children;
  12:     // ...    
  13:     public string ChildIds
  14:     {
  15:         get { return Children.Join( child => child.Id ); }
  16:     }
  17:     public string ChildNames
  18:     {
  19:         get { return Children.Join( child => child.Name ); }
  20:     }
  21: }

Cheers.

[Update Oct ‘09 In response to a number of comments on this post regarding problems with this approach, I’ve added a new blog entry with more details.  Check it out.]

Those with a SqlServer background will be familiar with the UPDATE .. FROM syntax. 

For example (totally made up)

   1: update employee_bonus
   2:    set bonus = 0 
   3:   from employee_bonus b 
   4:  inner join employees e on b.employee_id = e.employee_id
   5:  where e.bonus_eligible = 'N'

Those who transitioned from SqlServer to Oracle might find the absence of the UPDATE FROM a significant loss.  The best Oracle alternative that I know of is as follows.

   1: update (select bonus 
   2:           from employee_bonus b 
   3:          inner join employees e on b.employee_id = e.employee_id 
   4:          where e.bonus_eligible = 'N') t
   5:    set t.bonus = 0

Actually, if you look at it, they are very similar.

In fact Oracle has quite a bit of power in the UPDATE.  Check out this reference.  The syntax in the statement above utilizes the subquery1 block in the diagram below.

Happy coding.
 
Tags: ,

Introduction

In all honesty, this review may be a bit premature.  However, I wanted to record my thoughts and see if anyone listening shares them or has a difference of opinion.
I've been evaluating the SlickEdit Tools and have come up with a few top picks.  Also, I have identified some that make little difference to me.
First of all, the Tools are segregated into two products: Editing Toolbox and Versioning Toolbox.  I'll review them separately.

Editing Toolbox

Top Picks:

  • Acronyms - This one is quite nice.  I've created acronyms for namespaces that I use regularly.  In fact, I even wrapped the entire c# using statement in the acronym.  So, something like "umbc" can translate to something like "using My.Business.Controllers;"  I am now looking for patterns in my code that may benefit from Acronyms.  However, as I like to refactor to reduce code duplication, I don't know if I will find too many more uses for this feature.  Regardless, It does save time when starting up a new file.  Another positive that Acronyms provides is the ease by which to create new ones.
  • Code Annotations - I am not big on commenting code.  I prefer to let the code speak for itself.  If the code has trouble communicating, then I refactor it, such as renaming a method to clearly communicate the intent.  However, as a code reviewer, I can see great benefits to annotating the code for that purpose.  In the past, I have been in code reviews where the note taker's handwriting is suspect.  Also, the notes are on a hard copy that either gets filed away somewhere or scanned in.  I can see the benefit of using Code Annotations with code reviews on a projection monitor.  Assuming all participants review the code ahead of time, the meeting can run very smoothly.  And then you just send the annotation file to the team that owns the code.
  • Quick Profiling - I don't know how many times I wish I had a profiler at hand and was out of luck.  Clearly, adding a bunch of lines of code to record timestamps is not generally the best use of a developer's time.  Quick Profiling basically uses a trace handler and allows you to just write to the trace and you get profiling.  Of course, you are still adding lines of code to write to the trace, but it is a lot less than the other cheap alternative.  A true profiler is out of my budget as I suspect is the case for many of you.  I can see Quick Profiling saving me time guessing at where a bottleneck is.  I'm looking forward to testing it out on my next performance related issue.

Honorable Mention:

  • Load Files - This one looks pretty promising too.  If it weren't for the "Object reference" error I keep getting when I try to use it, it would be in the Top Picks.  This gives me a good opportunity to investigate customer support.
    I have used the MVC pattern quite a bit in my applications.  As you can imagine, there is some segregation of code between the Model, View, and Controller (not to mention the data context).  Though these components may be in different libraries and subfolders, they have similar names.  Because of this, using Load Files makes it convenient to load all of the related files at once.  Though I could certainly F12 a reference to open the related class, it's nice to be able to open the files in anticipation that I will need them.
    Another advantage, and possibly the biggest, is that you don't have to navigate solution explorer to the correct library and subfolder to find the file you want to open.

Indifference:

  • Auto Code Doc Viewer - As I said before, I am not big on commenting code.  Perhaps if I start publishing an API, this feature might come in handy.
  • C++ Code Navigation - The last time I saw C++ code was about 15 years ago.
  • Code Navigation - I'm not sure what this gives me that I don't already have with my C# editor (Ctrl+- and Ctrl+Shift+-)
  • Comment Wrapping - I have to admit, that when I do write comments, they are generally quite lengthy.  A sure sign that I probably need to spend more time thinking about the code and refactoring.  Regardless, this doesn't happen often enough for me to get much benefit out of this feature.
  • Directory Aliases - I don't browse directories very often; and when I do, the directories are relatively close to each other.  I don't see much of a time saver here.
  • Icon Extractor - I don't work with icons (nor Windows Forms) much.
  • Quick Launch - As far as I can tell, only beneficial if you also have the SlickEdit Application installed.
  • Regex Evaluator - This might be great if I didn't already write my own (and if there weren't already a bunch of online tools available).
  • Word Completions - The help is confusing on this one.  Perhaps I am just "slow".  Regardless, I use Visual Studios word completion all the time and I don't know how this can add much value.

 

Versioning Toolbox

Top Picks:

  • SVN Integration - I've been using AnkhSvn for almost a year now.  There are certainly some drawbacks to Ankh.  SlickEdit's integration seems to be more stable, which is why this is in my Top Picks.  However, Ankh does provide a bit more (for example, automatically performing an SVN Add when you create a new file).  Also, Ankh is open source (good and bad).
  • Find Version - This is a promising tool.  I know that I have had to dig through revisions to track down something that is causing problems.  This nifty little tool might have saved me a few hours searching.  On the flip side, I don't have this problem very frequently.
  • Who Wrote This? - Uses the history of your source file to show you who was the last person to touch each line of code.  This can come in handy.  I can quickly identify who I need to confer with if I have a question about the code.

Indifference:

  • Comparing Directories, Diff with Disk File, DIFFzilla - As I use SVN and Tortoise, I already have these types of tools.  In my opinion, the Tortoise tools are top notch.  I have used the diff/merge tool many times to compare two files on disk.  I just don't see the added benefit with SlickEdit's tools.
  • Version Graphs, Version History, Version Visualizations - These just don't seem like features I would need or use.
  • Backup History, How Old Is This?, When Was This Written? - I think good Agile / XP practices should eliminate the need for these tools.  For example, knowing which lines of code are more "stable" can be determined by looking at a history of failing tests.

 

Summary

As I said from the very beginning, this evaluation may be a bit premature.  Although the purpose behind these tools is to save development time, I don't want to take too much time learning how to use a new tool that won't give me a lot of benefit.  Don't get me wrong.  SlickEdit Tools for Visual Studio has a lot to offer.  At around $50 for each piece (Editing and Versioning), that's just a drop in the bucket when you consider the time you can save.  Even if just one feature provides a performance boost, it would be worth it.  I certainly plan to get my money's worth.
I'm convinced that if more people use the products that SlickEdit provides, they will only get better.  It's really up to the community to tell them what we want (perhaps refactoring tools, perhaps templates).  Imagine what they can gain from our experience.

I've had a few people ask me about my custom GridView and whether I can help them with theirs.  Though, I cannot share my code directly, I can provide some guidelines.  In the coming weeks I plan to post segments stepping through customizing a GridView.  My customizations are by no means perfect, and I have had to tweak things as I encounter issues. 

I look forward to sharing my experiences.  I will probably post a multi-part article that walks through customizing a GridView.  Again, I will not be posting any large chunks of code.  Mainly, I will provide guidelines that should meet the needs of most customizations.

Tags:
I'm clearly not the oldest knife in the drawer, nor am I the youngest.  I got involved with computers in my youth just about the time Bill Gates was positioning himself to put a PC in every home.  What this means is, I grew up on PCs with no mice; pre-Windows, pre-GUI.  I learned how to write "menu" programs that utilized a broader range of ascii characters than most people are familiar with today.  The point is, everything I did on the computer I did with the keyboard.

I recall in high school, a new kind of computer with this funny bulbous thing connected to it at the end of a wire.  The screen was even more compelling.  There was an arrow on the screen and you were supposed to use a "mouse" (the bulbous thing) to move it around.  Our teachers loaded something called Hypertext and told us to play around with it.  I have to admit, it was not love at first sight.  I had a lot of trouble making the arrow do what I wanted. 

Today, it is second nature to use a mouse to manipulate icons, text, forms, etc. on the screen.  Many people use touch screens in their daily lives.  As a developer who writes code, sometimes the mouse can get in the way.  The mouse is so integral that it can be hard to break free.  The mouse has its place; but, in my opinion, is should play a very small role in writing code.

I am constantly surprised at how many "experienced" developers are unfamiliar with the tools that they are using.  Below is a list of commands that I find useful with Microsoft Visual Studio, specifically for C# and asp.net.  Of course, you can change any of these and you can add your own by customizing Visual Studio. Many of these you will already know. Hopefully there are a few new ones here to boost your productivity.

These are just the basics.  Imagine what you can do with code acceleration tools like CodeRush, ReSharper, and others.

Keystroke Action
Navigation
F12 Go to Definition. Jumps to the definition of the Class, Method, Property, etc of the item currently occupied by the cursor. This works best if you have the source code.
Ctrl - Navigate Forward:  Jumps to last line of visited code. Jumps between source files. Can be used repeatedly.
Ctrl-Shift - Navigate Backward:  Jumps to next line of visited code. These are similar to going back and forward in your browser history.
Ctrl-Shift-F Find in files
Ctrl-G Go To Line.  Useful if someone says your code is failing at line 1739 of 2341.  Hopefully this never happens to you.
Ctrl-W S Activate Solution Explorer
Ctrl-W P Activate Properties Window
Ctrl-W O Activate Output Window
Ctrl-W E
Activate Errors List
Editing
Ctrl-Shift-R Record temporary macro
Ctrl-Shift-P Play temporary macro. I use these two to perform repetitive editing that refactoring tools cannot help with. As refactoring tools have gotten better, I have found that I use this less often.
Ctrl-Shift-S Save All
Ctrl-Shift-H Replace in files
Alt-A (When in Find and Replace dialog) Replaces all occurrences with the new text.
Ctrl-U Make lowercase
Ctrl-Shift-U Make uppercase
Ctrl-Space Complete a word (IntelliSense)
F2 Refactor Rename (I believe this is new to VS2008).  Will search entire solution to update any references.  Does a pretty good job with aspx too.
Ctrl-E D Format Document.  Useful for aspx and xml (if you don't mind Microsoft's formatting rules
Ctrl-M M Toggle outline expansion (note: the capital M here does not imply a "Shift", just used for readability)
Ctrl-M L Toggle All outlining
Building and Debugging
Ctrl-Shift-B Build All / Build Solution
Ctrl-F5 Start without debugging.
F9-Toggle breakpoint The first time I used visual studio I switch F5 and F9. Bonus points to anyone who knows why.
F5 Run with debugger
F10 Step over
F11 Step into
Shift-F11 Step out of