F# Tutorial

November 3, 2009 § Leave a comment

Here’s a great tutorial on F# written from the perspective of a developer already comfortable with C#. I’m just starting to play around with some functional development, and as this is a great jumping off point for someone that wants a quick introduction to F#, I thought I’d share.

.NET Web Services, Objects, WSDL.exe, and Reference.cs

October 15, 2009 § Leave a comment

This problem is annoying.

If you make a .NET web service and you add the web reference to another project, Visual Studio runs WSDL.exe in the background to create a Reference.cs file – which is awesome (sort of). The Reference.cs file gives you the ability to call your web service just as if it were any other .NET class you have a reference to, which again, is awesome (sort of).

The problem arises when you have a class defined that is accepted as a parameter to, or returned from, a method in your web service. WSDL.exe generates a class definition for this class in the Reference.cs file, which is great if you don’t want to reference the actual class.

The standard solution to this problem is much as Bruce Johnson describes, which is to hand-edit the Reference.cs file to remove the generated class, and add a “using” statement or fully qualify the class name to point to the correct (the original) namespace.

Unfortunately, this means that every time you need to update the web reference, and the Reference.cs file is regenerated, you need to hand edit the Reference.cs file, which is a huge waste of time and kind of a pain in the butt.

There is apparently a way to use SchemaImporterExtensions to affect the way that WSDL.exe generates the Reference.cs file, but to be honest, it looked really confusing and also difficult to maintain. I didn’t really attempt to do it, though, so maybe it’s easier than it looks.

So, after having to deal with this on a project I’m working with currently, I decided that it would make sense to automate this annoying problem. I built an executable that accepts, on the command line, the path to a dll, and the path to a Reference.cs file. The executable looks for any public classes or enums that are defined in both the dll and the Reference.cs file, removes the class declaration from the Reference.cs file, and fully qualifies the class references.

prebuildI then changed the project properties (in the project that contains the web references) to add several pre-build commands. The commands call the executable with whatever combination of dll’s and Reference.cs files. This way, you can update the web reference as often as necessary, and before the project builds, the executable will run and fix all the issues in the Reference.cs file.

This code is kind of hacked together, but I really had a hard time justifying spending much time on polishing it, so I’m just going to post it as is. It’ll only work on C#, and as far as I know, there aren’t any bugs, although you might have some. If you use it and find anything wrong with it, leave a comment, and I’ll update the code.

Anyway, here’s the code – I’m kind of surprised I couldn’t find something to do this already, so hopefully it’ll help you.

using System;

using System.Collections.Generic;

using System.Text;

using System.Reflection;

using System.IO;

using System.Text.RegularExpressions;

 

namespace WebServiceReferenceResolver

{

    class Program

    {

        /// <summary>

        /// Mains the specified args.

        /// </summary>

        /// <param name=”args”>The args.</param>

        static void Main(string[] args)

        {

            if (args.Length != 2)

            {

                Console.WriteLine(“Correct Usage: WebServiceReferenceResolver [ASSEMBLYNAME] [REFERENCE.CS]”);

                return;

            }

 

            try

            {

                string assemblyName = new FileInfo(args[0]).FullName;

                string referenceCsName = new FileInfo(args[1]).FullName;

 

                List<Type> classList = GetPublicClasses(assemblyName);

 

                StreamReader sr = new StreamReader(referenceCsName);

                string referenceCsSource = sr.ReadToEnd();

                sr.Close();

 

                // remove class definitions

                for (int i = classList.Count – 1; i >= 0; i–)

                {

                    bool typeFound = false;

                    referenceCsSource = RemoveClassDeclaration(referenceCsSource, classList[i], ref typeFound);

 

                    if (!typeFound)

                    {

                        classList.RemoveAt(i);

                    }

                }

 

                // properly resolve class references

                foreach (Type t in classList)

                {

                    referenceCsSource = ResolveClassReference(referenceCsSource, t);

                }

 

                StreamWriter sw = new StreamWriter(referenceCsName, false);

                sw.Write(referenceCsSource);

                sw.Close();

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.ToString());

            }

        }

 

        /// <summary>

        /// Gets the public classes.

        /// </summary>

        /// <param name=”assemblyName”>Name of the assembly.</param>

        /// <returns></returns>

        private static List<Type> GetPublicClasses(string assemblyName)

        {

            Assembly assembly = Assembly.LoadFile(assemblyName);

 

            Type[] types = new Type[0];

            try

            {

                types = assembly.GetTypes();

            }

            catch (ReflectionTypeLoadException rtle)

            {

                types = rtle.Types;

            }

 

            List<Type> returnList= new List<Type>();

            foreach(Type t in types)

            {

                if (t != null && t.IsPublic)

                {

                    returnList.Add(t);

                }

            }

 

            return returnList;

        }

 

        /// <summary>

        /// Removes the class declaration.

        /// </summary>

        /// <param name=”referenceCsSource”>The reference cs source.</param>

        /// <param name=”t”>The t.</param>

        /// <param name=”typeFound”>if set to <c>true</c> [type found].</param>

        /// <returns></returns>

        private static string RemoveClassDeclaration(string referenceCsSource, Type t, ref bool typeFound)

        {

            int startIndex = -1;

            typeFound = false;

 

            Regex r = new Regex(“(class|enum) “ + t.Name + ” ({|:)”);

            Match m = r.Match(referenceCsSource);

            if (m != null && m.Index != 0)

            {

                startIndex = m.Index;

            }

 

            if (startIndex != -1)

            {

                int firstBracketIndex = referenceCsSource.IndexOf(“{“, startIndex);

 

                int lastBracketIndex = referenceCsSource.LastIndexOf(“}”, startIndex) + 1;

                int lastSemicolonIndex = referenceCsSource.LastIndexOf(“;”, startIndex) + 1;

 

                if (lastBracketIndex > lastSemicolonIndex)

                {

                    startIndex = lastBracketIndex;

                }

                else

                {

                    startIndex = lastSemicolonIndex;

                }

 

                int characterIndex = firstBracketIndex + 1;

                int bracketIndexCount = 1;

                while (characterIndex < referenceCsSource.Length && bracketIndexCount > 0)

                {

                    if (referenceCsSource[characterIndex] == ‘{‘)

                    {

                        bracketIndexCount++;

                    }

                    else if (referenceCsSource[characterIndex] == ‘}’)

                    {

                        bracketIndexCount–;

                    }

 

                    characterIndex++;

                }

 

                if (characterIndex < referenceCsSource.Length)

                {

                    // remove it

                    typeFound = true;

                    referenceCsSource = referenceCsSource.Remove(startIndex, characterIndex – startIndex);

                }

            }

 

            return referenceCsSource;

        }

 

        /// <summary>

        /// Resolves the class reference.

        /// </summary>

        /// <param name=”referenceCsSource”>The reference cs source.</param>

        /// <param name=”t”>The t.</param>

        /// <returns></returns>

        private static string ResolveClassReference(string referenceCsSource, Type t)

        {

            // yeah, this is tacky, but whatever

            referenceCsSource = ResolveClassReference(referenceCsSource, t, string.Format(” {0} “, t.Name));

            referenceCsSource = ResolveClassReference(referenceCsSource, t, string.Format(” {0}[“, t.Name));

            referenceCsSource = ResolveClassReference(referenceCsSource, t, string.Format(” {0}(“, t.Name));

            referenceCsSource = ResolveClassReference(referenceCsSource, t, string.Format(“({0} “, t.Name));

            referenceCsSource = ResolveClassReference(referenceCsSource, t, string.Format(“({0}[“, t.Name));

            referenceCsSource = ResolveClassReference(referenceCsSource, t, string.Format(“({0})”, t.Name));

 

            return referenceCsSource;

        }

 

        /// <summary>

        /// Resolves the class reference.

        /// </summary>

        /// <param name=”referenceCsSource”>The reference cs source.</param>

        /// <param name=”t”>The t.</param>

        /// <param name=”matchString”>The match string.</param>

        /// <returns></returns>

        private static string ResolveClassReference(string referenceCsSource, Type t, string matchString)

        {

            int index = 0;

            while (index != -1)

            {

                index = referenceCsSource.IndexOf(matchString, index);

                if (index != -1)

                {

                    referenceCsSource = referenceCsSource.Insert(index + 1, string.Format(“{0}.”, t.Namespace));

                    index += t.Namespace.Length + matchString.Length;

                }

            }

 

            return referenceCsSource;

        }

    }

}

Universal Translation

September 17, 2009 § Leave a comment

This video discussing the concept of a universal translator is pretty cool.

I thought about writing something like this for the Android Developer Challenge just because it sounded fun, but ultimately decided I didn’t have time to do it. It shouldn’t be too hard – Cupcake already supports speech-to-text, Donut supports text-to-speech (and in the meantime, there are libraries like this one), and the Google Translate API is available to do the heavy lifting.

Obviously, implementing something like this on a mobile phone with out of the box technologies poses some issues, but the basic idea is cool, it’d be fun to play with, and it would come in handy in lots of situations. Hopefully someone with the time to work on it will put it together – I’d like to see how well it works.

I cheat at Bejeweled Blitz

August 19, 2009 § 28 Comments

bejeweled_blitz_25KSo, there’s this great game called Bejeweled Blitz. It’s basically the most evil game I’ve ever played. It sucks you in with the promise of glories and riches in return for only one minute of your time, and you find yourself wandering away from the computer in a stupor hours later wondering what happened and why you still haven’t gotten better than that 25K medal.

The problem, really, is that I suck at this game. The rules are deceptively easy, but it requires a quick pattern matching ability that I simply do not seem to possess. Oh, I do alright; I’ve managed to get 125K occasionally, but often it’s more in the 15K range. My wife (the temptress who started me on the journey into despair that I call Bejeweled Blitz) is fabulous at the game, and rarely scores less than 50K on any given game.

So, despite the fact that I suck at this game, and really, there’s no hope that I’ll ever really be good at it, I couldn’t stop playing it. It was taking away time from more productive pursuits, and I decided I needed to slay this evil dragon. While I might suck at playing Bejeweled Blitz, I’m pretty darn good at writing software. I thought that maybe, just maybe, if I spent my time writing a program to play Bejeweled Blitz, I might be able to beat my addiction and in the process, maybe learn a little something.

I’m happy to say that I was successful – I’ve beaten my addiction. Oh, I play it once in a while, but it’s largely lost its hypnotic power over my mind. It wasn’t easy, but the effort has paid off, and I’m a better person for it now. Here’s how I did it.

bejeweled_blitz_5I set up a windows forms project in Visual Studio, brought up the browser on my screen with Bejeweled Blitz already loaded in it, and started up the application.

Step one is getting the board off of the browser and into a program so that I can work with it. That’s just basic screen scraping, and is actually pretty simple. I set up textboxes on the form so that I can adjust the top, left, height, and width at runtime, depending on the position of the browser window and whatever variable information is loaded in the browser. Then, some code like this, and I’ve got a bitmap image of the screen.

    Rectangle r = new Rectangle(
        Convert.ToInt32(tbxX.Text),
        Convert.ToInt32(tbxY.Text),
        Convert.ToInt32(tbxWidth.Text),
        Convert.ToInt32(tbxHeight.Text));
    Bitmap bitmap = new Bitmap(r.Width, r.Height);

    using (Graphics g = Graphics.FromImage(bitmap))
    {
        g.CopyFromScreen(
            new Point(r.X, r.Y),
            new Point(0, 0),
            r.Size);
    }

bejeweled_blitz_4I can then display the bitmap on my form, so I can keep track of the difference (if any) between what’s displayed in the browser, and what my program has to work with.

Of course, just having a bitmap doesn’t do much for me, I have to translate that bitmap into a game board that I can work with in memory. I set up a class to represent a piece on the board like the following. The reason I track the color of the piece, as well as the “whiteness” of the piece, is because there are certain pieces in the game that *sparkle*, and using them scores more points. Tracking this part of the piece allows the program to make better decisions about which piece to move.

    public class Piece
    {
        public Color PieceColor { get; set; }
        public int PieceWhiteness { get; set; }

        public Piece()
        {
            PieceColor = Color.White;
            PieceWhiteness = 0;
        }
    }

I then create an 8×8 array of “Pieces”. Populating it is tricky, and actually gave me a lot of problems. I tried several different methods, but the one I finally settled on looks something like the following. I think the comments in the code explain most of what’s going on there.

    Random random = new Random();
    Bitmap bitmap = (Bitmap)pbBoard.Image;

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            board[i, j] = new Piece();

            // build up a whole array of colors for this piece
            // this is done to correct for minor errors/variations
            // when reading the different pieces
            // we use a random factor so that the same error isn't
            // repeated over and over when the color analysis/matching
            // is not completely correct
            List<Color> colors = new List<Color>();
            for (int k = 0; k < 5 + random.Next(15); k++)
            {
                for (int m = 0; m < 5 + random.Next(15); m++)
                {
                    int x = toX(i);
                    int y = toY(j);
                    colors.Add(bitmap.GetPixel(x - k, y - m));
                    colors.Add(bitmap.GetPixel(x - k, y + m));
                    colors.Add(bitmap.GetPixel(x + k, y - m));
                    colors.Add(bitmap.GetPixel(x + k, y + m));
                }
            }

            for (int colorCount = colors.Count - 1; colorCount >= 0; colorCount--)
            {
                // if the color is more or less white,
                // this adds to the whiteness, not the color
                int colorDiff = diff(colors[colorCount], Color.White);
                if (colorDiff < 100)
                {
                    board[i, j].PieceWhiteness++;
                    colors.RemoveAt(colorCount);
                }
            }

            // the only pieces with this much whiteness are
            // actually just white pieces
            if (board[i, j].PieceWhiteness > 100)
            {
                board[i, j].PieceWhiteness = 0;
            }

            // the color of the piece is the average of all the non-white(ish) pixels
            board[i, j].PieceColor = avg(colors.ToArray());
        }
    }

The “avg” and “diff” functions aren’t all that complicated, but it took me a few minutes to figure out how to diff and average colors. The code for that is as follows.

    private int diff(Color c1, Color c2)
    {
        double red = Math.Pow(Convert.ToDouble(c1.R) - c2.R, 2.0);
        double green = Math.Pow(Convert.ToDouble(c1.G) - c2.G, 2.0);
        double blue = Math.Pow(Convert.ToDouble(c1.B) - c2.B, 2.0);

        return (int)Math.Sqrt(blue + green + red);
    }

    private Color avg(Color[] colors)
    {
        int aTotal = 0;
        int rTotal = 0;
        int gTotal = 0;
        int bTotal = 0;

        foreach (Color c in colors)
        {
            aTotal += c.A;
            rTotal += c.R;
            gTotal += c.G;
            bTotal += c.B;
        }

        if (colors.Length == 0)
        {
            return Color.White;
        }
        else
        {
            return Color.FromArgb(
                (int)(aTotal / colors.Length),
                (int)(rTotal / colors.Length),
                (int)(gTotal / colors.Length),
                (int)(bTotal / colors.Length));
        }
    }

bejeweled_blitz_3So anyway, once I have the board built, I can also display that on the form so that I can debug errors and inconsistencies in that whole board translation process above. This isn’t exactly a flashy presentation, but it does the job that I needed.

Now, that’s the easy part – the hard part of this application was figuring out the best moves to make. There’s lots of different options – do you go from the top to the bottom, or the bottom to the top? Do you preferentially get 4 in a row to make more power gems, or do you blow up the power gems you already have? Do you try to think ahead and analyze the chain of events that will occur following each move? Can you do all of that fast enough that your program isn’t wasting time thinking about which move to make instead of just actually making the move? I’m not posting my code for this. If you want to cheat, you can do the work yourself. Suffice it to say, I figure out which move I want to make, but then I need to actually make it.

So, we’re just going to make the program play the game the same way you or I would play the game – it’s going to click on it. Here’s a handy little class to send mouse clicks. You can just pass the x and y coordinates that you want to click on, and it’ll take care of it.

    public class SendInputClass
    {
        //C# signature for "SendInput()"
        [DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
        static extern uint SendInput(
            uint nInputs,
            INPUT[] pInputs,
            int cbSize);

        //C# signature for "GetMessageExtraInfo()"
        [DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)]
        static extern IntPtr GetMessageExtraInfo();

        private enum InputType
        {
            INPUT_MOUSE = 0,
            INPUT_KEYBOARD = 1,
            INPUT_HARDWARE = 2,
        }

        [Flags()]
        private enum MOUSEEVENTF
        {
            MOVE = 0x0001,  // mouse move 
            LEFTDOWN = 0x0002,  // left button down
            LEFTUP = 0x0004,  // left button up
            RIGHTDOWN = 0x0008,  // right button down
            RIGHTUP = 0x0010,  // right button up
            MIDDLEDOWN = 0x0020,  // middle button down
            MIDDLEUP = 0x0040,  // middle button up
            XDOWN = 0x0080,  // x button down 
            XUP = 0x0100,  // x button down
            WHEEL = 0x0800,  // wheel button rolled
            VIRTUALDESK = 0x4000,  // map to entire virtual desktop
            ABSOLUTE = 0x8000,  // absolute move
        }

        [Flags()]
        private enum KEYEVENTF
        {
            EXTENDEDKEY = 0x0001,
            KEYUP = 0x0002,
            UNICODE = 0x0004,
            SCANCODE = 0x0008,
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MOUSEINPUT
        {
            public int dx;
            public int dy;
            public int mouseData;
            public int dwFlags;
            public int time;
            public IntPtr dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct KEYBDINPUT
        {
            public short wVk;
            public short wScan;
            public int dwFlags;
            public int time;
            public IntPtr dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct HARDWAREINPUT
        {
            public int uMsg;
            public short wParamL;
            public short wParamH;
        }

        [StructLayout(LayoutKind.Explicit)]
        private struct INPUT
        {
            [FieldOffset(0)]
            public int type;
            [FieldOffset(4)]
            public MOUSEINPUT mi;
            [FieldOffset(4)]
            public KEYBDINPUT ki;
            [FieldOffset(4)]
            public HARDWAREINPUT hi;
        }


        // This function simulates a simple mouseclick at the current cursor position.
        public static uint Click(int x, int y)
        {
            int vscreenWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
            int vscreenHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
            int vscreenLeft = System.Windows.Forms.Screen.PrimaryScreen.Bounds.X;
            int vscreenTop = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Y;

            // Absolute input requires that input is in 'normalized' coords - with the entire
            // desktop being (0,0)...(65535,65536). Need to convert input x,y coords to this
            // first.
            //
            // In this normalized world, any pixel on the screen corresponds to a block of values
            // of normalized coords - eg. on a 1024x768 screen,
            // y pixel 0 corresponds to range 0 to 85.333,
            // y pixel 1 corresponds to range 85.333 to 170.666,
            // y pixel 2 correpsonds to range 170.666 to 256 - and so on.
            // Doing basic scaling math - (x-top)*65536/Width - gets us the start of the range.
            // However, because int math is used, this can end up being rounded into the wrong
            // pixel. For example, if we wanted pixel 1, we'd get 85.333, but that comes out as
            // 85 as an int, which falls into pixel 0's range - and that's where the pointer goes.
            // To avoid this, we add on half-a-"screen pixel"'s worth of normalized coords - to
            // push us into the middle of any given pixel's range - that's the 65536/(Width*2)
            // part of the formula. So now pixel 1 maps to 85+42 = 127 - which is comfortably
            // in the middle of that pixel's block.
            // The key ting here is that unlike points in coordinate geometry, pixels take up
            // space, so are often better treated like rectangles - and if you want to target
            // a particular pixel, target its rectangle's midpoint, not its edge.
            x = ((x - vscreenLeft) * 65536) / vscreenWidth + 65536 / (vscreenWidth * 2);
            y = ((y - vscreenTop) * 65536) / vscreenHeight + 65536 / (vscreenHeight * 2);

            INPUT input_set = new INPUT();
            input_set.mi.dx = x;
            input_set.mi.dy = y;
            input_set.mi.mouseData = 0;
            input_set.mi.dwFlags = (int)(MOUSEEVENTF.ABSOLUTE | MOUSEEVENTF.MOVE);

            INPUT input_down = new INPUT();
            input_down.mi.dx = 0;
            input_down.mi.dy = 0;
            input_down.mi.mouseData = 0;
            input_down.mi.dwFlags = (int)MOUSEEVENTF.LEFTDOWN;

            INPUT input_up = input_down;
            input_up.mi.dwFlags = (int)MOUSEEVENTF.LEFTUP;

            INPUT[] input = { input_set, input_down, input_up };

            return SendInput(3, input, Marshal.SizeOf(input_set));
        }
    }

bejeweled_blitz_2So how does it work? It works fine – the program averages about 100K, I think it’s top score is 212,900, which is just a ridiculous score that I could never hope to get with my slow, pitiful human fingers.

It’s pretty fun to watch – the program just goes nuts, clicking away as quickly as possible – mouse pointer flying all about the screen, colors flashing and changing constantly.

I learned quite a bit from this little exercises, but mostly, I’m just happy I’ve exorcised my Bejeweled Blitz demon.

One Minute . . . GO!

Programmer Competency (Part 3)

August 19, 2009 § Leave a comment

Alright, I know I’ve had a bunch of posts on this lately, but self-reflection isn’t usually a bad thing (unless it prevents you from getting anything done, anyway), it interests me, and I seem to have come across a lot of good articles on the subject recently, so we’ll carry on with the theme.

I find that one of the best benchmarks for measuring your competency is to look at people that having proven their competency already. In this article on stifflog.com, several notable developers, including Dave Thomas (I’ve posted links here and here to the pragmatic programmers magazine), Steve Yegge, who really impressed me with this lecture he did last year regarding dynamic languages , and Bjarne Stroustrup (if you don’t know who he is, just stop reading now), answered a series of ten questions, with some answers that you’d expect, and some that you wouldn’t.

I wasn’t surprised that most of these developers were largely self-taught.  Most really great developers seem to have a natural talent for it that makes it easy for them to pick up technologies on their own.  This more than anything else is the thing that I think separates great developers from merely good developers – the ability to quickly learn and apply new technologies. I’ve posted before about the lack of practical knowledge a college degree imparts on most developers.

Steve Yegge, in response to the question of “What is the most important skill for a programmer?” had this to say:

Written and verbal communication skills. You’ll never make it very far as a programmer in any field unless you can get your ideas across to people effectively. Programmers should read voraciously, practice writing, take writing courses, and even practice at public speaking.

This is something that is overlooked by so many developers, I think. The ability to speak well, to write well, to effectively communicate and express your ideas and opinions is something that is indispensable, or at least should be. Articles like this one that have to spell out how to communicate with developers are unfortunately necessary because so many developers don’t understand how to effectively communicate with the business, their customers, and their coworkers.

Steve Yegge (I’m quoting him a lot, but hey – he’s smart!), in response to the question of “What is your favorite programming language?” had this to say:

I don’t have a favorite; I think they all suck. I tend to prefer Java because it’s a strong, portable platform with good tools and good libraries. But the Java language will evolve or die; it’s not good enough as-is to hold the lead indefinitely.

I found this pretty interesting, too. It reminds me of this article on lbrandy.com in which Louis Brandy talks about the process of going from hating a language, to loving it, and back to hating it. I can certainly sympathize with this. Oftentimes, the “rightness” of a solution can be inferred from its elegance and beauty. It’s frustrating when you have a problem that is very difficult to elegantly solve with the language that you are using. In fact, a strong case can be made that even design patterns are nothing more than a failing of your language. Jeff Atwood has written about this before on codinghorror.com.

There’s lots more good stuff in that interview, I’d certainly recommend reading it.

I think that this hasemanonmobile.com post sums it up succinctly, though. Really, the only two things that you need to be a good developer are communication and adaptability.

With that, maybe I’ll stop with the programmer competency articles – for a while, anyway.

.NET Exceptions – common exceptions and usage guidelines

August 9, 2009 § Leave a comment

My earlier post containing a list of all .NET exceptions gets a lot of traffic. It’s a great reference, but it’s also a really large list and doesn’t give much guidance regarding how to use them. This post will try to give some guidance regarding the more commonly used exceptions and in what circumstances they should be used.

Generally speaking, if you need to throw an exception purposefully, you should probably define a custom exception for that (read the bit about ApplicationException below). There are only a few of the built-in .NET exceptions that you’ll ever want to throw. Here’s my top 5 or so.

System

ApplicationException

The exception that is thrown when a non-fatal application error occurs.
The ApplicationException was originally intended as a base class for application specific exceptions. In other words, you’d derive from ApplicationException rather than Exception for any application specific exception types you needed to define. In practice, most developers don’t seem to do this. Honestly, I don’t know if it’s because they aren’t aware of it, or because it doesn’t really convey any particular benefits.

The obvious benefit of using this class is that if you have multiple application specific exceptions you want to define, and you do derive them all from ApplicationException, you can just catch the base class upstream and handle it. If you’re using a construct like the Microsoft Enterprise Library Exception Handling Application Block, this can come in very handy.

ArgumentException

The exception that is thrown when one of the arguments provided to a method is not valid.
This is a really handy exception that I use all the time. However, you should preferentially use one of the below exceptions. In other words, don’t do something like

throw new ArgumentException("parameter1 is null.");

when you could do something like

throw new ArgumentNullException("parameter1");

ArgumentNullException

The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.

ArgumentOutOfRangeException

The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method.

NotImplementedException

The exception that is thrown when a requested method or operation is not implemented.
This is a great exception that seems to hardly ever get used. Even some of the stuff that Visual Studio will generate automatically will do something like

throw new Exception("Method is not yet implemented.");

instead of

throw new NotImplementedException();

This obviously isn’t all of them, but it’s a start. The few exceptions I listed above, in combination with custom application-specific exceptions, account for about 90% of the exceptions I ever have to throw.

Are you a competent programmer? (Part 2)

August 9, 2009 § Leave a comment

As another take on my earlier post regarding programmer competency, this article examines the question from a different angle. Rather than the things you should know at particular levels, this iterates through some signs that you certainly are not a competent programmer as well as what you can and should do about it.

Of course, maybe this is unnecessary for you. Maybe you’re the best developer in the world.

Where Am I?

You are currently browsing entries tagged with development at Mike Vallotton's Blog.