Free Resources from FMS

Additional Resources

 

Thank you! Thank you! I just finished reading this document, which was part of a link in the recent Buzz newsletter. I have printed it for others to read, especially those skeptical on the powers of Access and its capabilities.

Darren D.

 

Free Catalog

 

Overloading on Overloads

Provided by: Scott Ellis, Vice President Advance Systems

This tip assumes you are familiar with the Object Oriented concept of method overloading. Even if you are not an expert in this area, but have used this feature in your code, the following is worth consideration.

Visual Basic .NET and C# both provide the mechanism of overloading. This functionality is built into the Common Language Runtime (CLR), but this feature works differently in Visual Basic .NET and C#. The exact method that the overloaded call resolves to is determined by the compiler. The runtime simply calls the method specified by the compiler. For this tip, we assume three projects.

  • A C# base library.
  • A C# application, with a reference to the base library.
  • A Visual Basic .NET application, with a reference to the base library.

1. The base library looks like this:

BaseClass.cs
using System;
    
namespace Base
{
      /// <summary>
      /// Summary description for Class1.
      /// </summary>
      public class BaseClass
      {
            public BaseClass()
            {
                  //
                  // TODO: Add constructor logic here
                  //
            }
    
            public void Test(MyClass mbc)
            {
                  System.Console.WriteLine("MyClass");
            }
      }
}


MyClass.cs
using System;
    
namespace Base
{
      /// <summary>
      /// Summary description for MyObject.
      /// </summary>
      public class MyClass
      {
            public MyClass()
            {
                  //
                  // TODO: Add constructor logic here
                  //
            }
      }
}

2. The C# application looks like this:

  CSDerived.cs

using System;

 

namespace CSDerived

{

  /// <summary>
  /// Summary description for Class1.

  /// <summary>

  public class CSDerived : Base.BaseClass

  {

    public CSDerived()

    {

      //

      // TODO: Add constructor logic here

      //

    }

 

    public void Test(object o)

    {

      System.Console.WriteLine("object");

    }

  }

}

  Main.cs

using System;

 

namespace CSDerived

{

  /// <summary>

  /// Summary description for Main.

  /// <summary>

  public class MainClass

  {

    static void Main()

    {

      CSDerived csdc = new CSDerived();

      Base.MyClass mbc = new Base.MyClass();

 

      csdc.Test(mbc);

 

    }

  }

}

3. The VB application looks like this:

  VBDerived.vb

Public Class VBDerived

    Inherits Base.BaseClass

 

    Public Overloads Sub Test(ByVal o As Object)

        System.Console.WriteLine("object")

    End Sub

 

End Class

  Main.vb

Public Class MainClass

    Shared Sub Main()

        Dim vbdc As VBDerived = New VBDerived()

        Dim mbc As Base.MyClass = New Base.MyClass()

        vbdc.Test(mbc)

    End Sub

End Class

When you run the C# vs. Visual Basic .NET application, the behavior of the "Test" call is different. This is an important, but subtle difference, so please pay attention. When you run the C# application, "object" is displayed on the console. When you run the VB application, "MyClass" is displayed. By all appearances, this code is the same in both the C# and Visual Basic .NET applications, but the result is different.

Why is this? C# resolves overloaded methods from the most derived class up to the base. In this case, it first looks at CSDerived, then at the base classes. Since the C# compiler finds a viable match in CSDerived, it resolves to this method without looking at the bases. Visual Basic .NET, on the other hand, looks all methods in derived and base classes simultaneously. It finds two matches, but the best one is in the base class, MyBase. It then resolves to the Test method in MyBase. This slight change in resolution can have wide ranging impacts on behavior, so it is something to watch out for as you develop class hierarchies. There is no workaround, and in fact there isn't even anything to workaround. This behavior is clearly defined in the C# and Visual Basic .NET language specifications.

There is a lot of discussion regarding the differences between C# and Visual Basic .NET, but this one is rarely discussed. I cannot say which is the "correct" behavior, but merely point out the differences. Intuitively, I would say that VB is more understandable, but I must refer you to the discussion by Paul Vick "Overloads" in VB.NET for the reasoning behind both decisions.

This behavior is correctly detected by Total .NET XRef! See FMS .NET XREF  for more information.

Return to the tips page