views:

231

answers:

4

I have the following code compiles without issue. Of course, I get an invalid cast exception when executing the Dim C As IDoThingsC = GetThing_C(). Am I missing something? Would you ever want to return an object that does not meet the interface requirement for a function return value?

Public Class ClassA

  Public Sub DoThings_A()
    Debug.Print("Doing A things...")
  End Sub

End Class


Public Class ClassB
  Implements IDoThingsC

  Public Sub DoThings_B()
    Debug.Print("Doing B things...")
  End Sub

  Public Sub DoThings_C() Implements IDoThingsC.DoThings_C
    Debug.Print("Doing C things...")
  End Sub

End Class


Public Interface IDoThingsC

  Sub DoThings_C()

End Interface


Public Class aTest

  Public Sub Test()

    Dim C As IDoThingsC = GetThing_C()
    C.DoThings_C()

  End Sub


  Public Function GetThing_C() As IDoThingsC

    Dim Thing As ClassA = New ClassA
    Thing.DoThings_A()

    Return Thing

  End Function


End Class
+13  A: 

Use Option Strict On at the top of your source code file to catch problems like this. You'll get a compile time error instead of a runtime error:

error BC30512: Option Strict On disallows implicit conversions from 'ClassA' to 'IDoThingsC'.
Hans Passant
+1 for Option Strict.
Will
Is it *still* possible to write VB code in this this-will-compile-cross-my-fingers-and-hope-to-die optimistic way? Why hasn't this been removed already?
Lasse V. Karlsen
Of course. Even better -- I have changed the Option Strict option in the compile options of the project (this way I don't have to add it to every code module).
JRS
A: 

If this was C#, your 'as' cast would result in C being null, which would result in a NullReferenceException. Not sure why VB.NET is throwing an ICE other than a different implementation of the 'As' keyword.

Interfaces are strongly typed. The compiler doesn't check for type safety for the 'as' keyword. Its apparently the same for the VB.NET compiler.

Will
+1  A: 

Taken from http://msdn.microsoft.com/en-us/library/h5fsszz9(VS.80).aspx

When converting between data types, the Visual Basic compiler can operate under strict or permissive type semantics. If strict type semantics are in effect, only widening conversions are permitted implicitly, and narrowing conversions must be explicit. Under permissive type semantics, you can attempt all widening and narrowing conversions implicitly. Type semantics apply to conversions between all data types, including object types.

Philippe Beaudoin
A: 

Option Strict will solve this problem. But also "ClassA" doesn't implement any interface. So, switching Class A's definition to the following will solve your problem:

Public Class ClassA
  Implements IDoThingsC

  Public Sub DoThings_A()
    Debug.Print("Doing A things...")
  End Sub

End Class
Rodney