Friday, July 21, 2006

 

.NET XML Gotcha

Ran into another little wrinkle earlier in the week.

XMLNode.SelectNodes() and XMLNode.SelectSingleNode() are very handy methods inside the DOM for jumping around inside XML documents. However, don't try to alter the nodes that are returned because they may not be live.

It took me several hours to track down a bug in my code caused by this. I noticed that, although the OwnerDocument of the nodes returned was correct, when I walked back up the tree by following the parents, I bump into a null before reaching the document node.

Firstly, it amazes me to think that it must have taken effort to program it to be less useful. Secondly, I dislike the uncertainty of it all...

Quote from the Help:
The XmlNode should not be expected to be connected "live" to the XML document.
That is, changes that appear in the XML document may not appear in the XmlNode,
and vice versa.

Thursday, July 20, 2006

 

Foible #1

I've come across an irritating little foible in C#, and I keep wondering whether it's me not thinking of the right solution, or it's a weakness of C# or .NET. Unfortunately, it's going to take a while to explain.

The short version is: You can't have a static abstract member.

The long version is...

I have written an extensible component. You add functionality (plug-ins) to it by writing additional assemblies and 'registering' them with the component.

The plug-ins must inherit from a public abstract class and I need them to implement their own version of a static property - we'll call it DataFormat.

I would like to implement it like this:

public abstract class MyBaseClass
{
    public static abstract string DataFormat { get; }

    // other stuff
}

But I can't! C# doesn't allow a member to be both abstract and static. So, I must remove one of those modifiers and keep the other, in order to compile.

If I keep the static modifier, i.e.

public abstract class MyBaseClass
{
    public static string DataFormat

    {
        get
        {
            return "";
        }
    }
}

... then I cannot ensure that the inheriting object implements its own version.

If I keep the abstract modifier, i.e.

public abstract class MyBaseClass
{
    public abstract string DataFormat { get; }
}


... then I need to create an instance of the object just to read a static value.

I originally took the first option, but it was painful. The reflection code was more complex and there was no early binding - you had to check at run-time that the object was written with a correct implementation of DataFormat.

So today I relented, and refactored to the second way. There's a lot less code, and it's strongly typed. I just have to instantiate the plug-in class when I need to read the DataFormat value.

This feels wrong, and yet I can't think of a better approach. Oh, and don't think Interfaces help, because they can't have static members.

 

Introduction

This is a documentation of my programming voyage of discovery.

I am primarily a Delphi programmer by trade, having been programming that language since Delphi 1 back in the mid 90's. Previously I'd been a Pascal programmer, only dabbling in C a little as my University didn't teach it (shocking!).

At the time of creating this blog, I am concentrating on C# and learning my way around .NET, although I juggle both Delphi and C# in my day job. Actually, programming is only about half of my job these days, as I have to perform recruitment, mentoring and technical liaison duties - the price of career progression. But I never intend to stop programming (I'm sure a lot of people say that).

I plan to use this blog to document some of the technical foibles I come across, as both a memory aid and a possible resource for others.

This page is powered by Blogger. Isn't yours?