2010-01-18 3 views
1

Quand en C#, nous avons les options de paramètres out et ref, en VB il y a une seule: ByRef.'out' question dans VB.NET

Maintenant, peu « problème » en essayant de « éliminer » l'avertissement du compilateur dire que test n'a pas été initialisé avant de passer comme argument:

Dim test As MyParsableClass ' = Nothing need imperatively?? ' 
' some code ... ' 
MyParsableClass.TryParse("value", test) ' warning on "test" here 

la classe brève déclaration:

Class MyParsableClass 

    Public Shared Function TryParse(ByVal value As String, _ 
    ByRef myParsableClass As MyParsableClass) As Boolean 
    myParsableClass = Nothing 
    If True Then 
     ' parse code OK' 
     myParsableClass = New MyParsableClass() 
     Return True 
    Else 
     ' parse code NOK ' 
     ' myParsableClass remains Nothing ' 
     Return False 
    End If 

    End Function 

End Class 

peut-être une solution était de déclarer

...Optional ByRef myParsableClass As MyParsableClass = Nothing) 

mais je ne peux pas définir ce paramètre comme facultatif. Que se passera-t-il si je le rate?

PS. (modifier) ​​

Dans le projet réel, ma classe « analysable » est MyHour avec Hour et Minute propriétés. J'ai écrit déjà le Parse(value as String) avec un FormatException, mais je pense que le code pourrait être plus clair, compact et rapide quand je ne vais pas utiliser essayer blocs catch ...

+1

Quelle est votre question exactement? –

+0

@divo: Comment éliminer l'avertissement (sans '# pragma' ou d'autres trucs similaires)? – serhio

+0

Y a-t-il un problème lorsque vous initialisez la variable locale avec 'Nothing'? –

Répondre

3

Je ne crois pas qu'il soit possible d'empêcher cet avertissement, sans affectation explicite.

Différentes langues ont des caractéristiques/installations différentes - si ce n'était pas le cas, il n'y aurait qu'un seul langage de programmation :-) Dans ce cas, oui, VB ne prétend pas qu'il existe deux types de paramètres ref, comme C# fait - en ce qui concerne le CLR, "out" n'existe pas.

Je ne suis pas sûr de ce que peSHIr parle - TryParse a été ajouté à des versions ultérieures de la BCL précisément la situation dans laquelle une analyse syntaxique est aussi susceptible d'échouer pour réussir - de sorte que vous pouvez prendre un chemin formation de failles sans avoir besoin d'une exception pour être jeté.

Modifier

Pour ajouter - la raison pour laquelle vous ne recevez pas un avertissement pour un grand nombre de types intégrés pour lesquels existe TryParse (par exemple Int32) est parce qu'ils sont types Structs/valeur, et donc toujours avoir une valeur. Si votre classe est assez simple, serait-il logique qu'elle soit une structure à la place?

+0

comme je l'ai mentionné, la classe (réelle) MyHour pourrait être vraiment une structure ... c'est une idée intéressante – serhio

+0

Je ne peux pas déclarer MyHour comme structure ... il est utilisé comme paramètres optionnels Les paramètres optionnels ne peuvent pas être des structures – serhio

+0

Les structures ne peuvent pas non plus avoir de constructeurs sans paramètres ni de membres protégés, leurs membres ne peuvent pas être initialisés lors de la déclaration, je ne peux pas implémenter IComparable avec Equals (objet) etc etc .. – serhio

0

Pas exactement une réponse à votre question, mais out and ref/ByRef are bad, alors pourquoi les utiliser en premier lieu? Beaucoup de développeurs pensent que le paradigme TryParse dans .NET Framework 1.0 était un mauvais choix. Pourquoi ne pas opter pour un MyParsableClass qui a une méthode Public Shared Function Parse(ByVal value As String) As MyParsableClass qui déclenche une exception appropriée en cas de besoin?

Ou même un Public Shared Function Parse(ByVal value As String) As MyParsableClassParsed où, MyParsableClassParsed est une aide classe interne qui contient deux propriétés: Success As Boolean et readonly Result As MyParsableClass? Vous pouvez toujours obtenir un résultat en appelant Parse, mais vous obtiendrez Success==True et Result==[whatever], ou simplement Success==False et Result==Nothing. Votre classe auxiliaire MyParsableClassParsed peut également utiliser un énumérateur au lieu d'un booléen et/ou une liste de messages d'erreur pour indiquer à l'appelant comment/pourquoi l'opération d'analyse a échoué. Ou l'exception de lancement peut avoir une telle valeur énumérée et/ou message (s) d'erreur.

Beaucoup plus facile à utiliser et plus flexible. Et tout sans ByRef pour vous donner des maux de tête/avertissements.

+0

En réalité, ma classe analysable est 'MyHour' avec les propriétés' Hour' et 'Minute'. Ce ne sera pas très clair si je vais ajouter aussi les propriétés 'Success' et' Result' ... J'ai déjà écrit 'Parse (value as String)' avec une exception FormatException, mais le code est plus clair, compact et rapide quand Je n'utilise pas try catch blocks ... – serhio

+0

Juste pour indiquer que tous les objets non dérivés de System.ValueType sont gérés par ByRef de manière implicite, c'est-à-dire que votre classe est ByRef que vous la spécifiiez dans la liste des paramètres de la méthode. – invert

+0

@Monkey: vous avez tort. ByRef peut définir la référence externe à rien à l'intérieur de la méthode d'appel, ByVal ne peut pas. – serhio