IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Passage à Option Strict On


Sujet :

VB.NET

  1. #1
    Membre éclairé
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Par défaut Passage à Option Strict On
    Bonjour,

    Voulant mettre un peu de rigueur (et peut-être améliorer la rapidité d'exécution) dans mon appli, j'essaye de passer à Option Strict On alors que j'ai développé celle-ci avec l'option Strict Off jusqu'ici

    Voici un petit bout de code que je n'arrive pas à adapter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Dim dt As DataTable = MonDataSet.Ma_dt
     
    ...
    Me.MonTableAdapter.Update(dt)
    La dernière instruction ne passe pas :

    Erreur 11 La résolution de surcharge a échoué, car aucun 'Update' accessible ne peut être appelé avec ces arguments*:
    'Public Overridable Overloads Function Update(dataRows() As System.Data.DataRow) As Integer'*: Impossible de convertir une valeur de type 'System.Data.DataTable' en 'Tableau à 1 dimension(s) de System.Data.DataRow'.
    'Public Overridable Overloads Function Update(dataRow As System.Data.DataRow) As Integer'*: Impossible de convertir une valeur de type 'System.Data.DataTable' en 'System.Data.DataRow'.
    'Public Overridable Overloads Function Update(dataSet As MonDataSet) As Integer'*: Impossible de convertir une valeur de type 'System.Data.DataTable' en 'MonAppli.MonDataSet'.
    'Public Overridable Overloads Function Update(dataTable As MonDataSet.Ma_dtDataTable) As Integer'*: Option Strict On interdit les conversions implicites de 'System.Data.DataTable' en 'MonAppli.MonDataSet.Ma_dtDataTable'. C:\Users\stephmag\Documents\Visual Studio 2010\Projects\MonAppli\MonAppli\MonForm.vb 41 17 MonAppli
    Je découvre que Update est en fait une fonction, et non une Sub, qui retourne un integer.

    Que faut-il faire sachant que CInt(Me.MonTableAdapter.Update(dt)) ne marche pas ?

  2. #2
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Ce n'est pas le fait que ce soit une fonction le problème (il est toujours possible d'ignorer le retour d'une fonction si on le souhaite) ; mais plutôt le type de l'argument qui ne colle pas
    Dim dt As DataTable = MonDataSet.Ma_dt
    Public Overridable Overloads Function Update(dataTable As MonDataSet.Ma_dtDataTable) As Integer'
    Update attend un MonDataSet.Ma_dtDataTable pas un DataTable à voir si tu peux directement typer comme il faut lors de la déclaration de dt.

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    une fonction peut etre appelée comme une sub, rien n'oblige à stocker la valeur de retour
    sinon cint n'a rien à voir dans la question, éventuellement dim r = appel_de_la_fonction()
    mais comme dit c'est facultatif d'assigner le retour

    par contre ici je ne vois pas pourquoi il t'embete, ton datatable est un datatable normal ou tu as fait un héritage ?
    tu as essayé avec update(ledataset) ?
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre éclairé
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Par défaut
    OK, pigé, c'est juste que j'ignorais qu'il existe un type MonDataSet.Ma_dtDataTable. j'aurais pu m'en douter en lisant bien le message d'erreur.

    Merci pour votre aide.

    J'ai un autre exemple de la même veine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    dim dr as datarow
    ...
    dr("chrono") = if(montextbox.text ="", DBNull.value, 3)
    J'ai un peu simplifié la ligne de code mais l'idée est que le champ "chrono" stocke un integer qui peut être DBNull dans certains cas.
    Or Integer et DBNull ne font pas bon ménage : "impossible de déduire un type commun" me dit-on lorsque je tente un Option Strict On.
    Comment fait-on dans ce cas ?

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    et là ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dr("chrono") = 3
    if montextbox.text = "" then dr("chrono") = DBNull.value

    sinon avec iif à la place de if ca fonctionne (je ne connaissais pas la syntaxe avec if tout court dans ce cas d'ailleurs)
    par contre autant que je peux comprendre qu'il râle (enfin limite quand même) je ne comprend pas pourquoi il ne râle pas dans les deux cas
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre éclairé
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Par défaut
    Merci pour le tuyau. Je connaissais IIf mais j'avais opté pour If après avoir lu dans MSDN que Iif évalue systématiquement les 3 arguments alors que If n'évalue que les 2 premiers si la condition de l'argument 1 est vraie.
    Bizarrement, en effet, ça marche très bien avec Iif. Je n'aurais jamais pensé à chercher une solution de ce côté là.

    Du coup, j'ai enfin réussi à lever toutes les "erreurs" signalées lors du passage à Strict On (plus de 200 au total).

    Il me reste à tester l'appli et voir si je sens une différence en matière de performance.
    J'avoue que je reste assez dubitatif. bien que VB.NET soit théoriquement plus rapide avec l'option Strict On (ce qu'on comprend bien sur le principe du fait que les tests de cohérence sont effectués lors de la compilation, c'est au prix d'une débauche de conversions (ctype, Cint, Cbool, .toString, etc...).

    On va voir. Si je détecte une amélioration, j'en témoignerai dans ce topic.

  7. #7
    Membre éclairé
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Par défaut
    Bon, ben c'est pas flagrant, j'ai effectué une 10 lancements de mon appli en chronométrant la séquence de démarrage (en ms).
    - 2 séries pour la version 77 qui comporte l'option strict On
    - 1 série pour la version 76 qui n'avait pas l'option strict On

    La moyenne arithmétique plaide en faveur de la V76 mais vu l'écart-type, cela n'est pas significatif.

    Nom : Capture.JPG
Affichages : 638
Taille : 29,0 Ko

  8. #8
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    j'aurais pas pensé que ca serait plus performant
    ca permet de faire du code plus propre et d'éviter quelques bugs, c'est déjà ca
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  9. #9
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    sinon avec iif à la place de if ca fonctionne (je ne connaissais pas la syntaxe avec if tout court dans ce cas d'ailleurs)
    par contre autant que je peux comprendre qu'il râle (enfin limite quand même) je ne comprend pas pourquoi il ne râle pas dans les deux cas
    L'opérateur If (parce qu'il s'agit bien d'un opérateur dans ce cas) requiert que ces 2 derniers opérandes soient du même type ou que l'un soit implicitement convertible vers le type de l'autre (la doc est plutôt mal faite au passage laissant croire que ces opérandes sont considérés de type Object là où il est juste dit que ça accepte n'importe quel Object ). Par contre le type de retour (autrement dit le type de la variable à laquelle on assigne le résultat) ne rentre pas en ligne de compte pour la détermination du type "commun" mentionné. Résultat là on a d'un côté un Integer et de l'autre un DBNull et il n'existe pas de conversion implicite (certes DBNull implémente IConvertible mais c'est une implémentation explicite donc requiert un cast vers IConvertible) ; du coup seul Object peut-être possible, mais Option Strict interdit un type de retour implicite vers Object.
    Ainsi les seules possibilités seraient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim r1 = If(condition, DBNull.Value, CObj(3)) ' cast explicite vers Object, r1 a pour type Object
    Dim r2 = If(condition, DirectCast(DBNull.Value, IConvertible), 3) ' cast explicite vers IConvertible, r2 a pour type IConvertible
    ' à la rigueur
    Dim r3 = If(condition, DirectCast(DBNull.Value, IConvertible).ToInt32(provider), 3) ' utilisation de IConvertible.ToInt32, r3 a pour type Integer
    ' bon après on peut tout imaginer
    Dim r4 = If(condition, DBNull.Value.ToString, 3.ToString) ' r4 aura pour type String
    mais bon en gros r2 r3 (et r4 ?) sont inutiles, r2 et r3 parce que IConvertible.ToInt32 balance une exception dans son implémentation explicite pour DBNull (et pour r4 DBNull.Value.ToString renvoie String.Empty)
    D'un autre côté la fonction IIf (parce que là il s'agit bien d'une [en fait de 2] fonction définie dans le module Microsoft.VisualBasic.Interaction) existe en 2 versions l'une générique IIf(Of T) qui prend donc ces 2 derniers opérandes de type T et renvoie un T (et là on retombe dans le même schéma qu'évoqué avec If) et surtout l'autre surcharge qui prend 2 Object et renvoie un Object donc là comme c'est explicite dans la signature ça passe
    Sinon comme l'a mentionné noftal, la différence entre If et IIf c'est le court-circuitage IIf(foo IsNot Nothing, foo.bar, other) plantera (parce foo.bar est quand même évalué) alors que If(foo IsNot Nothing, foo.bar, other) fonctionnera

    Citation Envoyé par noftal Voir le message
    - 2 séries pour la version 77 qui comporte l'option strict On
    - 1 série pour la version 76 qui n'avait pas l'option strict Off
    C'est pas un peu la même chose ? s'il n'y avait pas Off c'est que ça comportait On

    Citation Envoyé par noftal Voir le message
    Il me reste à tester l'appli et voir si je sens une différence en matière de performance.
    J'avoue que je reste assez dubitatif. bien que VB.NET soit théoriquement plus rapide avec l'option Strict On (ce qu'on comprend bien sur le principe du fait que les tests de cohérence sont effectués lors de la compilation, c'est au prix d'une débauche de conversions (ctype, Cint, Cbool, .toString, etc...).
    Citation Envoyé par Pol63 Voir le message
    j'aurais pas pensé que ca serait plus performant
    ca permet de faire du code plus propre et d'éviter quelques bugs, c'est déjà ca
    Comme Pol63 mais j'argumente, Option Strict On ou Off ne change pas le moment où sont faits les "tests de cohérence".

    Option Strict On permet 3 choses uniquement (avec les réglages d'avertissement/erreurs par défaut) :
    1. Interdire les conversions implicites restrictives (et uniquement elles) soit
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      Dim i As Integer = 32768
      Dim s1 As Short = i ' Option Strict Off
      Dim s2 As Short = CShort(i) ' Option Strict On
      ' Note: dans l'autre sens (de Short vers Integer) avec ou sans le flag pas besoin de cast explicite
      Le fait que ça plante ou pas après n'a rien à voir avec Option Strict (mais plutôt avec l'option avancée de compilation qui active/supprime la vérification des overflow [et qui elle peut avoir une incidence sur les perfs])
    2. Interdire le typage implicite avec Object ; comme évoqué plus haut sur l'histoire du If, donc aucune incidence sur les perfs non plus (c'est juste préciser au lecteur ce qui se passe de toute façon)
    3. Et enfin Interdire les liaisons tardives (le late binding, soit le "dynamic" façon VB.Net qui existe depuis la V1 de VB.Net quoique maintenant peut-être que ça passe aussi par le DLR comme le dynamic de C# [ou c'était déjà comme ça et ça a été étendu à C# bref je digresse là ])
      Là à la rigueur oui ça peut avoir un impact mais il faut déjà utiliser la liaison tardive (ce qui implique qu'on est conscient que ça dégrade les perfs à la base) et en plus utiliser Option Strict On (avec les réglages d'avertissement/erreurs par défaut) empêche de toute façon la liaison tardive donc oblige à faire différemment (et comparer des perfs sur une telle logique de code différente c'est comme comparer la vitesse d'un bateau cargo et d'un avion de chasse )

  10. #10
    Membre éclairé
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Par défaut
    C'est pas un peu la même chose ? s'il n'y avait pas Off c'est que ça comportait On
    Euh, oui, il y a une coquille. Je corrige dans le message initial (mais je pense que tu avais corrigé de toi-même)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Repeater et XML avec Option Strict "On"
    Par boivsam dans le forum ASP.NET
    Réponses: 0
    Dernier message: 15/10/2009, 19h34
  2. Option Strict On ET OpenMode.Binary
    Par Tropic dans le forum VB.NET
    Réponses: 8
    Dernier message: 25/08/2009, 08h05
  3. VB.Net / Option Strict On
    Par sandre dans le forum ASP.NET
    Réponses: 5
    Dernier message: 15/07/2009, 17h37
  4. Probleme : option strict on rejette toute liaison tardive
    Par Roken62 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 21/04/2009, 16h20
  5. Ecriture class (classe) Latex -- passage option -- style
    Par osfdeb dans le forum Mise en forme
    Réponses: 0
    Dernier message: 16/03/2009, 17h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo