Thursday, June 09, 2005

I've recently been wondering why Microsoft, in their infinite wisdom, has decided to provide helper code in both C# & VB.Net that promotes bad OOP coding.

Have you ever implemented an interface in either language?

Well, Visual Studio - in 2002, 2003 & Whidbey - auto-creates the implementation signatures in both languages and marks them "Public". I'm sure you know that.

Now this is a big problem in both C# & VB.Net. Let's see why in C# first.

If I write this code:

      class Module
      {

            [STAThread]
            static void Main(string[] args)
            {
                  ClassY InstanceY = new ClassY();
                  ((IFoo)InstanceY).DoMethod();
                  ((IBar)InstanceY).DoMethod();
                  InstanceY.DoMethod();
                  Console.ReadLine();
            }
      }
 
      public interface IFoo {void DoMethod();}
      public interface IBar {void DoMethod();}
 
      public class ClassX : IFoo   
      {
            public void DoMethod() {Console.WriteLine("IFoo.DoMethod");}
      }
 
      public class ClassY : ClassX, IBar
      {
            public void DoMethod() {Console.WriteLine("IBar.DoMethod");}
      }

Visual Studio complains with "The keyword new is required on 'ConsoleApplicationCSharp.ClassY.DoMethod()' because it hides inherited member 'ConsoleApplicationCSharp.ClassX.DoMethod()'".

So I insert "new" on "DoMethod()" in "ClassY", like this:

      public class ClassY : ClassX, IBar
      {
            public new void DoMethod() {Console.WriteLine("IBar.DoMethod");}
      }

My output becomes:

IFoo.DoMethod
IBar.DoMethod
IBar.DoMethod

Pretty much what I should expect, but I'm a conscientious programmer so I want to avoid "new" (or "shadows" in VB.Net) so I mark the "ClassY" method as "private" rather than "public", like so:

      public class ClassY : ClassX, IBar
      {
            private new void DoMethod() {Console.WriteLine("IBar.DoMethod");}
      }

The output now becomes:

IFoo.DoMethod
IFoo.DoMethod
IFoo.DoMethod

When I explicitly call the "IBar" interface method it calls the method of the class that doesn't even implement the interface. That's crazy!

So, to avoid the problem I declare the implementation explicitly:

      public class ClassX : IFoo   
      {
            void IFoo.DoMethod() {Console.WriteLine("IFoo.DoMethod");}
      }
 
      public class ClassY : ClassX, IBar
      {
            void IBar.DoMethod() {Console.WriteLine("IBar.DoMethod");}
      }

Now, of course, the code that calls the "DoMethod()" on the native "InstanceY" object can't see either method. But isn't that what we really would want to do? It avoids any ambiguity.

Let's look at a similar thing in VB.Net. My code is now this:

    Module Main
        Sub Main()
            Dim InstanceY As New ClassY
            CType(InstanceY, IBar).DoBar()
            CType(InstanceY, IFoo).DoFoo()
            InstanceY.DoBar()
            InstanceY.DoFoo()
            Console.ReadLine()
        End Sub
    End Module
 
    Public Interface IFoo
        Sub DoFoo()
    End Interface
 
    Public Interface IBar
        Sub DoBar()
    End Interface
 
    Public Class ClassX
        Implements IFoo
        Public Sub DoBar() Implements IFoo.DoFoo
            Console.WriteLine("IFoo.DoFoo")
        End Sub
    End Class
 
    Public Class ClassY
        Inherits ClassX
        Implements IBar
        Public Sub DoFoo() Implements IBar.DoBar
            Console.WriteLine("IBar.DoBar")
        End Sub
    End Class

Notice that since I'm being a nasty programmer I've swapped the Names of the method implementations. Think of it like replacing "Save" with "Delete".

Now of course, what happens? My dear user runs this code and gets the following:

IFoo.DoFoo
IBar.DoBar
IBar.DoBar
IFoo.DoFoo

Again, the answer is to explicitly declare both implementations "Private". It avoids any ambiguity.

But the answer is not to enforce the use of "Private". Apart from the times when "Protected" is needed, there may well be a need for the developer to make an implementation of an interface "Public" or "Friend".

So, my open question, why has Microsoft made "Public" the default for implementation of interfaces?

posted on Thursday, June 09, 2005 7:21:00 PM (Cen. Australia Standard Time, UTC+09:30)  #    Comments [0] Trackback
 Monday, June 06, 2005

I've just recently discovered the cool set of Wikicities (http://www.wikicities.com/wiki/List_of_Wikicities).

Some are junk and useless, but others, like the Star Wars wiki (http://starwars.wikicities.com/wiki/Main_Page) are very cool and comprehensive. They are all very much like the venerable Wikipedia (http://www.wikipedia.com).

Now, let's bring Groove into this picture.

Groove Virtual Office (http://www.groove.net) is about setting up a workspace for collaboration within a group of people. The richness of Groove is, in some ways, far better than the wikis. You get threaded discussions, group calendars, forms, etc. But in other ways the wiki is king. I know that I can find out very excellent information from a wiki just by searching it. Groove is poor at searches.

So, now with Microsoft purchases Groove I think there is an interesting possibility here.

Microsoft has SharePoint - the intranet collaboration tool. Groove can be used to sync SharePoint spaces into a Groove workspace that can be shared with Groove users across the web. There is a clear link between a smart client and a web site.

Why not have the same between a wiki and Groove? Can you imagine a corporate wiki that can be synched into Groove and taken on the road. Each update silently makes its way through the internet to keep all Groove Wiki users up-to-date with all the coporate knowledge, procedures, clients, projects, etc, etc, etc.

Cool huh?

(Microsoft, please open a new Groove space and/or blog to tell us where Groove is going. Please?)

posted on Monday, June 06, 2005 11:03:48 AM (Cen. Australia Standard Time, UTC+09:30)  #    Comments [2] Trackback

I get a very odd thing with this new dasBlog.

I have to click the "Add Entry" tab twice for it to work. Not a double-click, instead the first time I click it I get a message saying that an internal error has occured. The second time I click it all is good.

Me thinks that there is something amiss with the new caching stuff.

posted on Monday, June 06, 2005 10:54:01 AM (Cen. Australia Standard Time, UTC+09:30)  #    Comments [2] Trackback