Backward compatability not Backwards compatability

I was at a client site the other day and one of the developers asked me if it was possible to get the name of the assembly that had made a call to a specific function within a class.

I told him to use the Assembly.GetCallingAssembly() static method in the System.Reflection namespace and pointed him to an example of it's use in one of our c# classes.

He then thanked me and went off to add the call to his code. 

I thought that the matter was done, but a little later he came back and told me that it didn't work. It seems that it was always returning the Microsoft.VisualBasic namespace.

Now I knew that he was writing the code in VB but I couldn't believe that there was a bug in this method... one that I'd used on several times before with no problems.

I rewrote his code in C# and sure enough... It worked!  But the VB code always returned Microsoft.VisualBasic....

Then I set about trying to figure out why.

After a lot of hair pulling and google-ing to no avail, I finally figured it out:

Consider the following class:

 using System.Reflection;

class MyClass

{

public string WhoCalledMe()

{

return Assembly.GetCallingAssembly().FullName;

}

}

 

And now the VB code that instantiates it and calls the WhoCalledMe method:

 ' VB source code

Dim x

Dim caller as string

x = New MyClass()

' This returns Microsoft.VisualBasic....!

caller = x.WhoCalledMe()

 

 

The reference to the object that contained the call to Assembly.GetCallingAssembly() was not properly declared.

Instead of strongly typing the reference variable, it was declared un-typed... and since the compiler option was not set to "Option Strict", this was allowed.

This means that there is some sort of Microsofty magic going on here to resolve the late bound call through... you guessed it... the Microsoft.VisualBasic assembly.

The moral of this story is:  Backward compatibility is great when you need it... but you have to be careful to make sure it doesn't turn into BACKWARDS compatibility.