This could also happen for any "Public member on type not found" combinations.

This can happen any time you have a late-bound method call in VB .Net that does not exist in the object. In my case, the short answer is that you cannot late-bind extension methods!

In VB .Net, if you specify concrete types for your variables and/or function return types, then the compiler can early-bind the calls and work out exactly what is pointing to what. If you have mistyped, Visual Studio can show you where you've gone wrong. If the compiler doesn't know what the type is, it cannot determine if the method even exists until runtime, at which point it might fall over with a MissingMemberException.

Dim earlyBound As String = MyFunction()

earlyBound.BadMethod()       ' Compiler error, String does not contain the member BadMethod

Public MyFunction() As String

   Return "something"

End Function

 

' Late bound example

Dim myVariable = MyFunction()

myVariable.DoSomething()       ' Late-bound, the compiler doesn't know what type myVariable is

Public Function MyFunction()

   Return "something"

End Function

So what about extension methods? 

An extension method is a static method in a static class that the compiler interprets on your behalf. An extension method always has a first "this" parameter of the target type and the compiler effectively converts this:

myString.ExtensionMethod()

into this

ExtensionClass.ExtensionMethod(myString)

That is all fine except for one important detail. The extension methods must reside in a different class to the class they are targetting because they must be in a static class.

Why is this an issue? Image we have a StringExtensions class and one method called TruncateLongString(string As String, length As Integer) and imagine we have the following late-bound code:

Dim myVariable = MyFunction()         ' MyFunction returns a string but the compiler does not know this

myVariable.TruncateLongString(50)    ' Compiler will allow this and will make a late-bind attempt

At runtime, when the code is actually executed, what actually happens under the covers would be something like this:

Dim myVariable = MyFunction()

myStringVariable = CType(myVariable, String)  ' Since I now know it is a String

myStringVariable.TruncateLongString(50) ' MissingMemberException: String does not contain TruncateLongString(), which is correct, it doesn't!

So how do we avoid this? Use types for your Functions and ideally your variables.