Rant of the day: IDisposable

My colleagues are probably used to the fact that I rant about code quality frequently. I take code quality very seriously. Not because I’m especially expert in it, but because features of basic code quality make it easier for other people to read and maintain the code.

Today’s irritation comes from some code (replicated in a number of classes I might add) that implements IDisposable. It is a fine interface and by implementing it you are telling the rest of the world that you have some stuff that can’t just be left to the garbage collector to clean up. These are things like file streams, database connections, etc. Any type of scarce resource that you want to hand back as soon as you are finished with it rather than leave it up to the garbage collector.

However, I came across this “gem” in some code today where the class, basically a utility class, contained no fields (so it wasn’t holding on to anything at all, let alone anything that might be a scarce resource). Yet, for some reason it implemented IDisposable. What was it going to dispose? What could it dispose?

The answer was in the code:

public void Dispose()
{
    // Nothing to dispose of.
}

Quite!

The StackOverflowException

Take a look at the following code:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            RecurseForever();
        }
        catch (StackOverflowException)
        {
            Console.WriteLine("Caught Stack Overflow Exception");
        }
        catch (Exception)
        {
            Console.WriteLine("Caught general Exception");
        }

        Console.ReadLine();
    }

    static void RecurseForever()
    {
        RecurseForever();
    }
}

What do you think the output of the program will be?

If you had asked me a few days ago I’d have said the output would be “Caught Stack Overflow Exception”, however that isn’t the case. If you run the code in the debugger this is what you actually get:

StackOverflowException

The exception simply isn’t caught.

If the application isn’t being debugged it will simply end at this point. It goes directly to jail. It does not pass GO. It does not collect £200.

ConsoleApplication2 has stopped working

I guess I've never needed to do this before…

I guess I’ve never created a struct in a while (at least in Visual Studio 2008 using C# 3.0) because I’ve just discovered that the Automatic Properties don’t work in structs.

I’ve just created this struct:

public struct CapacityUnit
{
    public string Name { get; private set; }
    public long Multiplier { get; private set; }

    public CapacityUnit(string name, long multiplier)
    {
        Name = name;
        Multiplier = multiplier;
    }
}

Which at first glance looks okay except that I get a compiler error in the constructor on Name. The reason for this is that structs need to have the fields initialised before the this object can be used. Name uses this implicitly as in this.Name. So, it would seem that there is no way, at least as far as I can see, to initialise these properties when using Automatic Properties as I would need to use an implicit this.

Formatting dates the hard way

I was doing a bit of a code review and I spotted this in the code base.

string[] splitOptions = new string[1] { dayEarlier.Date.Year.ToString() };
string[] earlyDates = dayEarlier.Date.GetDateTimeFormats();
string[] earlySplit = earlyDates[67].Split(splitOptions,
    StringSplitOptions.RemoveEmptyEntries);
earlySplit[0] = earlySplit[0].Replace(",", string.Empty);

Essentially the code gets the date in a specific format. However, it does it in the oddest most convoluted way I’ve ever seen.  Just to explain, here is the code again but this time I’ve added some comments:

// dayEarlier is a business object with a property called Date that returns a DateTime.
// splitOptions will contain the year in an 1-element string array.
string[] splitOptions = new string[1] { dayEarlier.Date.Year.ToString() };

// earlyDates will contain the dayEarlier Date in umpteen different formats.
string[] earlyDates = dayEarlier.Date.GetDateTimeFormats();

// earlySplit will contain the 68th (!) formatted date (out of 89 that get generated).
// Element 0 in this array will contain the bit upto the year, element 1 will contain
// the bit after the year. The year itself is discarded.
string[] earlySplit = earlyDates[67].Split(splitOptions,
    StringSplitOptions.RemoveEmptyEntries);

// The first element (element 0) of earlySplit is then modified to remove the comma.
earlySplit[0] = earlySplit[0].Replace(",", string.Empty);

In short, what is actually being looked for is the day name, day of the month and the month. That’s it. And that, apparently, isn’t even in the 89 permutations of the date that .NET generated in the second line of code. To add to the potential problems with this, I’ve not seen any documentation that states that the permutations given by this method will stay the same.

All this code could easily be re-written simply as:

dayEarlier.Date.ToString("ddd dd MMM");

And the bonus here is that we are not generating 88 completely useless permutations, nor are we generating the permutation that is simply the closest match that we still have to futz around with. We are generating the date in exactly the format that we want. (Current culture permitting)

Throwing exceptions

When reviewing some code today I noticed some code that catches an exception, does something with it and then explicitly throws it again. The code looked something like this:

try
{
    // Do something that might cause an exception
}
catch (Exception ex)
{
    // Some stuff
    throw ex;
}

The problem with the above code is that when you throw the exception again the details about where the exception originated from are lost because the throw populates that part of the exception object. So the original details are replaced with the details about the current location in the code.

Consider the following program:

static void Main(string[] args)
{
    try
    {
        A();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
    Console.ReadLine();
}

private static void A()
{
    B();
}

private static void B()
{
    try
    {
        C();
    }
    catch (Exception ex)
    {
        // I can do something
        Console.WriteLine("Method C() catches the exception and partly handles it");
        Console.WriteLine();
        throw ex;
    }
}

private static void C()
{
    D();
}

private static void D()
{
    Exception ex = new Exception("This exception is thrown in D");
    throw ex;
}

The original exception is thrown by method D. The code in method B catches the exception and partly handles it, it then explicitly throws the original exception again. When the exception is finally caught in the Main method the call stack is truncated to method B. It can no longer see that method C and D were also called.

The output of the application is:

Method C() catches the exception and partly handles it

This exception is thrown in D
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 40
   at ConsoleApplication1.Program.A() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 26
   at ConsoleApplication1.Program.Main(String[] args) in d:DevelopmentConsoleA
pplication1ConsoleApplication1Program.cs:line 14

As you can see, the stack trace only goes from the point of the second throw to the point that the exception is caught.

There are two correct solutions to this problem.

Solution 1: Wrapping the Exception

If you have additional information to add to the exception object you can create a brand new Exception and then put the original exception in as an inner exception like this:

try
{
    // Do something that might cause an exception
}
catch(Exception ex)
{
    // Some stuff
    Exception moreDetailedEx = new Exception("A message with more details", ex);
    throw moreDetailedEx;
}

NOTE: Please use a specific exception class and not Exception this makes catching specific types of exception easier and more efficient as the compiler can put in place some optimisations for you over you catching the base Exception class and examining it. I’m using Exception here simply to make the example easier to read.

So, if we change our program above to create a new exception and wrap the old one in it it will now look like this:

static void Main(string[] args)
{
    try
    {
        A();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.InnerException.Message);
        Console.WriteLine(ex.InnerException.StackTrace);
        Console.WriteLine();
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
    Console.ReadLine();
}

private static void A()
{
    B();
}

private static void B()
{
    try
    {
        C();
    }
    catch (Exception ex)
    {
        // I can do something
        Console.WriteLine("Method C() catches the exception and partly handles it");
        Console.WriteLine();
        Exception newEx = new Exception("This exception is thrown in B", ex);
        throw newEx;
    }
}

private static void C()
{
    D();
}

private static void D()
{
    Exception ex = new Exception("This exception is thrown in D");
    throw ex;
}

I’ve added some extra bits to the Main method to show the InnerException details too. The output of the program now looks like this:

Method C() catches the exception and partly handles it

This exception is thrown in D
   at ConsoleApplication1.Program.D() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 56
   at ConsoleApplication1.Program.C() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 50
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 36

This exception is thrown in B
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 44
   at ConsoleApplication1.Program.A() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 29
   at ConsoleApplication1.Program.Main(String[] args) in d:DevelopmentConsoleA
pplication1ConsoleApplication1Program.cs:line 14

As you can now see all the information is available. It can now be seen the patch from the final point the exception was caught to the point it was originally thrown.

Solution 2: Re-throwing the Exception

If you do not have any additional information to add to the exception you can simply use the throw keyword on its own and it will keep the existing exception object without altering it. For example:

try
{
    // Do something that might cause an exception
}
catch (Exception ex)
{
    // Some stuff
    throw;
}

Changing our program above to use the throw statement on its own will mean the program now looks like this:

static void Main(string[] args)
{
    try
    {
        A();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
    Console.ReadLine();
}

private static void A()
{
    B();
}

private static void B()
{
    try
    {
        C();
    }
    catch (Exception ex)
    {
        // I can do something
        Console.WriteLine("Method C() catches the exception and partly handles it");
        Console.WriteLine();
        throw;
    }
}

private static void C()
{
    D();
}

private static void D()
{
    Exception ex = new Exception("This exception is thrown in D");
    throw ex;
}

And the output now looks like this:

Method C() catches the exception and partly handles it

This exception is thrown in D
   at ConsoleApplication1.Program.D() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 52
   at ConsoleApplication1.Program.C() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 46
   at ConsoleApplication1.Program.B() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 40
   at ConsoleApplication1.Program.A() in d:DevelopmentConsoleApplication1Cons
oleApplication1Program.cs:line 26
   at ConsoleApplication1.Program.Main(String[] args) in d:DevelopmentConsoleA
pplication1ConsoleApplication1Program.cs:line 14

As you can see the stack trace now shows you the entire route between the point the exception was caught and when it was thrown. We can also see from the message that the method C still caught and partly handled the exception.

Using the throw keyword like this actually translates to the CIL (MSIL) rethrow command. When you use throw with an Exception object it translates to the CIL throw command.

When the exception is thrown in D the CIL looks like this:

.method private hidebysig static void D() cil managed
{
    .maxstack 2
    .locals init (
        [0] class [mscorlib]System.Exception ex)
    L_0000: nop
    L_0001: ldstr "This exception is thrown in D"
    L_0006: newobj instance void [mscorlib]System.Exception::.ctor(string)
    L_000b: stloc.0
    L_000c: ldloc.0
    L_000d: throw
}

The key above is L_000d where it throws the exception.

Compare that to method B:

.method private hidebysig static void B() cil managed
{
    .maxstack 1
    .locals init (
        [0] class [mscorlib]System.Exception ex)
    L_0000: nop
    L_0001: nop
    L_0002: call void ConsoleApplication1.Program::C()
    L_0007: nop
    L_0008: nop
    L_0009: leave.s L_0020
    L_000b: stloc.0
    L_000c: nop
    L_000d: ldstr "Method C() catches the exception and partly handles it"
    L_0012: call void [mscorlib]System.Console::WriteLine(string)
    L_0017: nop
    L_0018: call void [mscorlib]System.Console::WriteLine()
    L_001d: nop
    L_001e: rethrow
    L_0020: nop
    L_0021: ret
    .try L_0001 to L_000b catch [mscorlib]System.Exception handler L_000b to L_0020
}

In the above CIL code the key is L_001e where it rethrows the exception. This is where the CIL is much more explicit than C#. In C# the throw keyword is overloaded and functions differently depending on whether it receives an exception object or not.

Drawing lines on the map with the Virtual Earth ASP.NET control

This uses the July 2008 CTP of the Windows Live tools. You can download the Windows Live Tools for Visual Studio.

In this post, we’re taking a look at drawing lines on the map with the Virtual Earth ASP.NET control.

In the a previous post (Using PushPins with the Virtual Earth ASP.NET control) I showed how to create a Shape object that represents a point on the map. In that post the Shape constructor took a parameter that described the type of object and a point. With Polylines more than one point is required. To construct an appropriate Shape object a list of points is needed. A point is represented by an LatLongWithAltitude object.

List<LatLongWithAltitude> points = new List<LatLongWithAltitude>();

Once the list is populated the Shape can be created:

Shape result = new Shape(ShapeType.Polyline, points);

Alternatively, it is possible to defer the addition of the points until a later time by assigning them through the Points property.

Lines and Pushpins

One thing you have to be careful of when creating shapes that are lines (or polygons, but we’ll come to that later on) is that by default a pushpin is also displayed to go along with the line (see right) in order to give the user something to hover over so they can gain more information. If these pushpins are not desired then the IconVisible property needs to be set to false.

shape.IconVisible = false;

On the other hand, if a pushpin is desired for each line then you can control where the pushpin appears. By default they are somewhere along the middle of the line. The IconAnchor property can be set to the point at which the pushpin is to appear. For example, to set the pushpin to appear at the start of a line use:

shape.IconAnchor = shape.Points[0];

You can also do the other customising of the pushpin as I showed you in my previous post (Using PushPins with the Virtual Earth ASP.NET control).

Customising the Line

There are also many ways to customise the line as well. You can change the colour and width of the line on the Shape object.

In the example on the left the data has been customised to reflect two attributes. The data is rail services in Scotland and includes information on the route, start and end stations, the length of the route and the train franchise operator.

In the example, the train franchise operator is reflected in the colour of the lines while the length of the route is reflected in the width of the line. The shorter suburban routes are quite thin lines, while the intercity lines are much thicker.

The LineWidth property accepts the width in pixels of the line, while the LineColor property accepts a Color object (from the Microsoft.Live.ServerControls.VE namespace). The Color object allows you to specify the standard red, green and blue values (each 0-255) along with an alpha blend value (a double from 0 to 1.0).

Line Generalisation

So far this is pretty easy, however, what appears on the map isn’t necessarily what you put into the Shape object. Virtual Earth generalises the shape that you create, presumably to improve performance. I suspect the idea was to generalise in a way that the user wouldn’t notice, however, it some situations it is very obvious that the line is not displaying its original points.

Take a look at these two maps. They both display exactly the same data. One is just a zoomed in version of the other (I’ve enlarged the zoomed out version so they are the same size to make them easier to compare).

The map on the left shows the naturally zoomed in version. The one on the right shows the zoomed out version (which I then resized back so that both maps are the same size for this blog post)

Because central Scotland is quite busy and has a lot of rail routes, have a look at the routes in the Highlands (north of Scotland) to see this phenomenon more easily. Take the most northern route for example. The map on the left shows it weaving in and out of the mountains reasonably clearly, while the map on the right shows the route slightly more straightened out. Also the map on the right doesn’t even appear to hit some of the points.

 

Technorati Tags: ,,

Errors like these drive me insane

Today I was trying to fix up a website for one of our clients. I got the site out of source control but somehow or other it wouldn’t compile. I’m not going to talk about the fact it didn’t compile out of the box – We all know that is not a good situation and the person who allows source to get into a state like that needs to be slapped repeatedly with a wet fish.

What I’m going to talk about is what the eventual error turned out to be because it is not something I’ve ever seen before and it was such a bizarre thing that I can only hope it isn’t common. But if you are afflicted by it you will be pleased to know that the solution is easy, even if the discovery of what the problem actually was wasted several hours.

If you are reading this then I suspect you will probably be suffering from this problem in which case you are probably now yelling “STOP BABBLING MAN AND TELL ME WHAT TO DO”.

First, a description of the problem:

There is an ASP.NET web site project (probably does the same thing on a web application… And let’s not get in to why this is a web site project, it’s an old project and the standard now is web applications) with a number of web forms in it.

The ASPX for the default page currently looks something like this:

<%@ Page Language="C#" AutoEventWireup="true"
      CodeFile="Default.aspx.cs" Inherits="Default" %>
<html>
<head><title></title></head>
<body>
    <form id="form1" runat="server">
        Stuff that's on my page
        <asp:Label ID="MyLabel" runat="server"></asp:Label>
    </form>
</body>
</html>

Nothing too odd about that, you might say… And you’d be right. There is nothing at all wrong with this page. However, when you go to compile your website you get this error:

Infuriation 2
The name ‘MyLabel’ does not exist in the current context

But… but… but… You can see that MyLabel exists on the ASPX page and if you type in the C# or VB source file you’ll see that intellisense finds the object perfectly well. So what is going on?

Well, it is interesting to note that Page1 and Page2 are very similar to Default. In fact, so similar that when they were created the person that did this just copied Default.aspx and Default.aspx.cs (or Default.aspx.vb if that’s your poison). What they didn’t do when they made the copies was to change the page directive at the top that has the Inherits attribute that points to Default. So, Page1 and Page2 are inheriting the behaviour in Default.

When this first happened that wasn’t a problem. Page1 and Page2 had just minor cosmetic differences, the behaviour was the same and no one noticed.

At some point later someone came along and added MyLabel to Default.aspx… This still didn’t make a difference. Everything worked as normal.

Then someone came along and realised that MyLabel needed to change on some condition and added some code into the Default.aspx.cs file that modified MyLabel. At this point all hell broke loose!

Suddenly, MyLabel can’t be found and no one can figure out why. It is there on the ASPX page, intellisense picks it up, the stupid compiler can’t see it.

The Solution

Eventually, after spending a couple of hours on the problem and batting it around some collegues and doing bit of brainstorming someone (let’s call him Craig Muirhead because he figured it out in the end and deserves the credit) comes up with the idea that perhaps other pages are inheriting the wrong class. A quick find in files on the name of the class and we found it was referenced by 4 other pages. It takes a matter of moments to fix all those files to point to their respective code behind files/classes rather than the one on our hapless page. And all of a sudden everything compiles.

Technorati Tags: ,,,,

Using PushPins with the Virtual Earth ASP.NET control

This uses the July 2008 CTP of the Windows Live tools. You can download the Windows Live Tools for Visual Studio.

In this post, we’re taking a look at using pushpins with the Virtual Earth ASP.NET control. We have a page similar to the previous post, with a map control on it called VEMap.

In the code behind we have a method for adding shapes to the map as this is a multi-step process. First we need to create an object to represent the point, then an object to represent the shape (we’ll come to other shape types later, but for the moment, we’re just dealing with pushpins), finally we add the shape to the map.

The Page_Load method adds a number of shapes to the map, these pushpins represent locations where Scottish Developers have held user group meetings. The code looks like this:

protected void Page_Load(object sender, EventArgs e)
{
    // Glasgow Caledonian University
    AddShape(55.8662120997906, -4.25060659646988);

    // Dundee University
    AddShape(56.4572643488646, -2.97848381102085);

    // Microsoft Edinburgh (George Street)
    AddShape(55.9525336325169, -3.20506207644939);

    // Microsoft Edinburgh (Waterloo Place)
    AddShape(55.9535374492407, -3.18680360913277);
}

private void AddShape(double latitude, double longitude)
{
    LatLongWithAltitude point = new LatLongWithAltitude(latitude, longitude);
    Shape shape = new Shape(ShapeType.Pushpin, point);
    VEMap.AddShape(shape);
}

From this we get a fairly standard output when the application is run:

At present, this is all visual. There isn’t any real functionality. What we’ll do is add some very basic functionality, so that when you hover over a pushpin it tells you something about it. The Shape object has a Description property into which you can put an HTML fragment. So, here is the updated code:

protected void Page_Load(object sender, EventArgs e)
{
    // Glasgow Caledonian University
    AddShape(55.8662120997906, -4.25060659646988,
        "<b>Glasgow Caledonian University</b>");

    // Dundee University
    AddShape(56.4572643488646, -2.97848381102085,
        "<b>Dundee University</b>");

    // Microsoft Edinburgh (George Street)
    AddShape(55.9525336325169, -3.20506207644939,
        "<b>Microsoft Edinburgh</b> (George Street)");

    // Microsoft Edinburgh (Waterloo Place)
    AddShape(55.9535374492407, -3.18680360913277,
        "<b>Microsoft Edinburgh</b> (Waterloo Place)");
}

private void AddShape(double latitude, double longitude, string description)
{
    LatLongWithAltitude point = new LatLongWithAltitude(latitude, longitude);
    Shape shape = new Shape(ShapeType.Pushpin, point);
    shape.Description = description;
    VEMap.AddShape(shape);
}

The result when you hover over a pushpin looks like this:

That’s all great if you want the default pushpin look. However, you might want to customise the pins so they match more what you are looking for. The Shape class has a CustomIcon property which you can set to be a graphics object. In the following example I’ve used a simple png file with a red circle and an semi-transparent yellow fill.

The code now looks like this:

private void AddShape(double latitude, double longitude, string description)
{
    LatLongWithAltitude point = new LatLongWithAltitude(latitude, longitude);
    Shape shape = new Shape(ShapeType.Pushpin, point);
    shape.Description = description;
    shape.CustomIcon = "images/target.png";
    VEMap.AddShape(shape);
}

And the result looks like this:

Finding things with Virtual Earth

This uses the July 2008 CTP of the Windows Live tools. You can download the Windows Live Tools for Visual Studio.

This is a very introductory post just to show how to find things using the Virtual Earth ASP.NET control.

First you need to add an assembly reference to the Virtual Earth control to your project:

In each page that you want to use the Virtual Earth control you must add a line that looks like this at the top of the file:

<%@ Register Assembly="Microsoft.Live.ServerControls.VE"
    Namespace="Microsoft.Live.ServerControls.VE"
    TagPrefix="ve" %>

This registers the assembly allowing you to use the control.

When you view the ASPX page you will see that you have additional tools in the toolbox that relate to Virtual Earth. The one we are going to look at in this post is the Map control.

From the tool box you can drag a map control onto your design surface. The code it generates will set up a default position and zoom level which centres on the continental United States.

By default the control is a 400x400px square and has been given a name of Map1:

<ve:Map ID="Map1" runat="server" Height="400px" Width="400px" ZoomLevel="4" />

 

To start with we are going to change the defaults to something that is closer to home (well, mine at least) and centre it on central and southern Scotland and zoom in somewhat. I also don’t like the name Map1 so I’m going to change that too:

<ve:Map ID="VEMap" runat="server" Height="600px" Width="400px" ZoomLevel="8"  Center-Latitude="55.75" Center-Longitude="-3.5" />

The first thing I should comment on is the zoom level because it doesn’t really mean anything to anyone. Personally, I’d like to say “here’s a bounding box for the area I want to see, you figure out how to do that and sort out the aspect ratio for me”. Then again, maybe that’s because when I wrote a GIS system for my final year project at university that was what I did. I didn’t constrain the user to specific and artificial zoom levels. The maths behind it isn’t difficult and a modern graphics card can do that with its proverbial eyes closed. Having said that I can understand why it was done that way. It means that none of the maps are generated on the fly, it is all based on pre-existing graphic files that are retrieved as needed. This means no strained servers trying to render maps.

The zoom level ranges from 1 to 19. 1 is zoomed out to the whole world and 19 is zoomed in to street level. In between that it seems to be mostly an matter of experimentation.

As it stands the program will display a map on the page and you can zoom in or out, pan around and change display modes and so on, just like Live Maps.

Next, we’ll add some functionality to find stuff. To that end a text box (SearchTextBox) will be added in order that we can type stuff in, and a button (SearchButton) that we can submit it. The code for the button click event is as follows:

protected void SearchButton_Click(object sender, EventArgs e)
{
    VEMap.Find(string.Empty, SearchTextBox.Text);
}

The two parameters on the Find method match the two text boxes you find on Live Maps. The first parameter is the “what” (i.e. the business name or category” and the second parameter is the “where” (i.e. The address, location or landmark). If you use Live Maps a lot you’ll probably already by used to just ignoring the first box, so I haven’t included anything to populate that parameter and will just leave it empty.

Now, when the application is run the map will update when the button is clicked. It will zoom to the location you’ve specified.

At present there is no mechanism to determine where to move the map to if there is any ambiguity. For example, type “Bolton” and you’ll be taken to Bolton, England rather than Bolton, NY. Type “Washington” and you’ll be taken to the District of Columbia rather than the state. On the other hand type WA (the standard two letter abbreviation for Washington State) and you will be taken to Washington state.

The Virtual Earth control can tell you about all the places that it thought about when it was deciding where to take you. To get that we have to handle the ServerFind event on the map control. In order to do that change the ASPX markup to read:

<ve:Map ID="VEMap" runat="server" OnServerFind="VEMap_ServerFind"  Height="600px" Width="400px" ZoomLevel="8"  Center-Latitude="55.75" Center-Longitude="-3.5" />

And then add a handler in the code behind:

protected void VEMap_ServerFind(object sender, FindEventArgs e)
{
    StringBuilder sb = new StringBuilder();

    foreach (Place place in e.Places)
    {
        sb.Append("<p><strong>");
        sb.Append(place.Name);
        sb.Append("</strong> (");
        sb.Append(place.MatchCode);
        sb.Append(")<br/>");
        sb.AppendFormat("Lat: {0}, Long: {1}", place.LatLong.Latitude, place.LatLong.Longitude);
        sb.Append("</p>");
    }
    ResultLiteral.Text = sb.ToString();
}

Note: A Literal control called ResultLiteral has also been added to the page to display the results.

The ServerFind event will be raised by the map control when it finds stuff, however, you’ll notice that the page does not include the text we’ve built up. You might be thinking at this point that the event isn’t being raised at all, but put a break point down inside the code of the event. You’ll see the breakpoint is being hit.

The problem is that the ServerEvent is being handled as part of an AJAX postback rather than a page postback. If you look at the stack trace you’ll see that the map control has its own internal UpdatePanel that you would normally need to indicate that part of the page was AJAXified, so to speak. So to ensure that the code works as we would expect it to we need to add some things to the ASPX file.

First off we need a ScriptManager:

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>

And secondly we need an update panel of our own in order to put the controls that will be updated when the ServerFind event is handled. So the update panel, with the controls we created earlier, looks something like this.

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
    <p>
        Search:
        <asp:TextBox ID="SearchTextBox" runat="server" />
        <asp:Button ID="SearchButton" runat="server" Text="Search"
          onclick="SearchButton_Click" />
    </p>
    <p>
        <asp:Literal ID="ResultLiteral" runat="server" />
    </p>
    </ContentTemplate>
</asp:UpdatePanel>

If we search for Bolton again the results look like this:

As you can see there are several Boltons in the world.

The FindEventArgs contains many bits of information, but in the sample above we’ve just concentrated on the Place. This gives you details of the places that have been found, how good a match it thinks the place is and where the place actually is. Obviously, the more specific you are in the search the more accurate the results are going to be and the more chance you have of getting an exact match.

Note: At present there is not much documentation for the Virtual Earth ASP.NET control. Much of the functionality has been gleaned from reading the documentation for the “classic” Virtual Earth control which is customisable through Javascript. I also found a bug, which has been reported to Microsoft, that if you happen to be in Birds Eye view then the find functionality does not work.

Method hiding or overriding – or the difference between new and virtual

When developing applications it is very important to understand the difference between method hiding and method overriding.

By default C# methods are non-virtual. If you are a Java developer this may come as a surprise. This means that in C# if you want a method to be extensible you must explicitly declare it as virtual if you want to override it.

So, what is overriding? Wikipedia has a succinct definition. Method overriding is a language feature that allows a subclass [aka derived class] to provide a specific implementation of a method that is already provided by … its [superclass] [aka base class]. The implementation in the subclass overrides (replaces) the implementation in the superclass.

The important thing to remember about overriding is that the method that is doing the overriding is related to the method in the base class.

Method hiding, by contrast, does not have a relationship between the methods in the base class and derived class. The method in the derived class hides the method in the base class.

I wouldn’t personally recommend method hiding as a strategy for developing code. In my opinion, if you feel the need to hide the method on the base class then you are most likely doing something wrong. I haven’t come across any scenarios where method hiding couldn’t be better implemented by other means, even as simple as just naming the method on the derived class to something else.

Let’s look at some code to show you what I mean. First off we are going to use this class structure (it’s my favourite when showing off inheritance, and you may have seen variations of it already on my blog).

Partial Class Diagram

Let’s say that the Dog class has a method call Bark()

public class Dog: Mammal
{
    public void Bark()
    {
        Console.WriteLine("Woof!");
    }
}

So far, so good. We can call it like this:

static void Main(string[] args)
{
    Dog d = new Dog();
    d.Bark();
    Console.ReadLine();
}

And the output of the program is as you’d expect. “Woof!” is written to the console.

Now, Chihuahuas are nippy wee things and they tend to “yip” rather than “woof” so what we’ll do is create a Bark() method in Chihuahua class that writes out “Yip!” instead.

public class Chihuahua : Dog
{
    public void Bark()
    {
        Console.WriteLine("Yip!");
    }
}

What happens here is that the C# compiler will display a warning to indicate that it has found a situation that it can guess at the intended functionality, but it really wants to to be explicit.

warning-message

‘Animals.Chihuahua.Bark()’ hides inherited member ‘Animals.Dog.Bark()’. Use the new keyword if hiding was intended.

By inserting the new keyword between the public and the void in the method declaration we can get rid of this warning. We are being explict and telling the compiler that we know what we are doing. So, what are the implications of method hiding? Consider the following bit of code:

static void Main(string[] args)
{
    Dog d = new Chihuahua();
    d.Bark();
    Console.ReadLine();
}

Well, if you have a Dog reference that actually refers to an instance of the Chihuahua class then when you call bark it will still say “Woof!” That goes against many people’s expectations. This is because you’ve actually drawn that line in the sand and are saying that the Bark method on Chihuahua is unrelated. If you hold a reference to a Dog then you may not be expected to know about the existence of a Chihuahua so if your calling code suddenly got the functionality of the Bark method in the Chihuahua class then it might break. The CLR cannot make that decision for you. If you do know about your Dog reference actually being a Chihuahua then you must cast it before using it. However, that means you are likely to have to litter your code with conditional statements based on the actual type of the object and that defeats the power of having an object oriented language.

What you should have done is make the Bark method virtual then overriden the derived version like this:

public class Dog : Mammal
{
    public virtual void Bark()
    {
        Console.WriteLine("Woof!");
    }
}
public class Chihuahua : Dog
{
    public override void Bark()
    {
        Console.WriteLine("Yip!");
    }
}

This way when you have a Chihuahua object then the correct Bark method is called regardless of the type of the reference so long as the reference type can see a Bark method on that hierarchy

The way I see it is that there is no reason to have to draw that line in the sand and use the new keyword in the context of method hiding. If you feel the need to do that then your two realistic options are either to consider whether what you really want to do is make the base virtual and then override in the derived class, or whether you need to think of a better name for the method in the derived class. If the methods are related (like the Bark example above) then method overriding is what you need. If they are not related then make that explicit by giving the method in the derived class a different name.