2010-01-08 5 views
4

Je compile le code suivant sans problème. Bien sûr, j'obtiens une exception de distribution invalide lors de l'exécution du Dim C As IDoThingsC = GetThing_C(). Est-ce que je manque quelque chose? Souhaitez-vous jamais retourner un objet qui ne répond pas à l'exigence d'interface pour une valeur de retour de fonction?Pourquoi les interfaces ne sont pas fortement typées?

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 
+0

Je ne vois pas comment il est compilé? Est-ce que je manque quelque chose? –

+0

Est-ce que * vraiment * compiler sans problèmes? Je pense que "GetThing_C" ne serait pas compilé car il tente de retourner une instance ClassA en tant qu'interface IDoThingsC, qu'il n'implémente pas. –

+0

C'est ce que je pensais. Il compile dans Visual Studio 2005 et dans Visual Studio 2010 Beta 2. – JRS

Répondre

13

Utilisez Option Strict On en haut de votre fichier de code source pour attraper des problèmes comme celui-ci. Vous obtiendrez une erreur de compilation au lieu d'une erreur d'exécution:

error BC30512: Option Strict On disallows implicit conversions from 'ClassA' to 'IDoThingsC'. 
+5

+1 pour Option Strict. – Will

+6

Est-il * encore * possible d'écrire du code VB dans cette manière optimiste de vouloir-compiler-croiser-mes-doigts-et-espérer-mourir? Pourquoi cela n'a-t-il pas déjà été supprimé? –

+2

Bien sûr. Encore mieux - j'ai changé l'option Option Strict dans les options de compilation du projet (de cette façon je n'ai pas besoin de l'ajouter à chaque module de code). – JRS

1

Taken de 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.

0

Option Strict résoudra ce problème. Mais aussi "ClassA" n'implémente aucune interface. Ainsi, en changeant la définition de la classe A à la suivante résoudra votre problème:

Public Class ClassA 
    Implements IDoThingsC 

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

End Class