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 :

comment gerer des paramètres de type variable dans une fonction ou une procédure


Sujet :

VB.NET

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Gérant
    Inscrit en
    Août 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut comment gerer des paramètres de type variable dans une fonction ou une procédure
    bonjour,

    j'essaye d'écrire une classe qui permet de lire un fichier "à la manière" du pascal, c'est à dire permettant de lire directement des variables typées.

    voici le code de ma classe :

    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Public Class TFileType
        Private TypeSize As Integer
        Private fs As FileStream
     
        Public Sub New(ByVal tSize As Integer, ByVal FileName As String)
            TypeSize = tSize
            fs = New FileStream(FileName, FileMode.Open, FileAccess.ReadWrite)
        End Sub
        Public Sub free()
            fs.Close()
        End Sub
        Public Function eof() As Boolean
            Return (fs.Position = fs.Length)
        End Function
        Function read(ByRef Buffer As Object) As Integer
            Return fs.Read(buffer, 0, TypeSize)
        End Function
        Public Sub write(ByRef Buffer As Object)
            fs.Write(Buffer, 0, TypeSize)
        End Sub
     
    End Class
    j'utilise la classe de cette façon :

    je voudrais lire un fichier article

    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
         Public Structure TArticle
            Dim codbar1 As Integer
            Dim codbar2 As Integer
            Dim LongueurChaine As Byte
            <VBFixedString(30)> Dim nom As String
            Dim famille As Byte
            Dim remise As Byte
            Dim prix As Integer
            Dim actif As Byte
        End Structure
     
        Const CheminFichierArticle As String = "E:\ARTICLE"
     
        Dim fa As New TFileType(46, CheminFichierArticle)
        Dim article as TArticle
        fa.read(article)
        fa.free()

    un problème ce pose avec le méthode read ( et write ) de ma classe :

    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        Function read(ByRef Buffer As Object) As Integer
            Return fs.Read(buffer, 0, TypeSize)
        End Function

    la méthode read devant lire des types différents, j'utilise un buffer de type Object , mais le compilateur refuse en me disant qu'il ne peut pas transtyper un TArticle en Object

    ma question :
    comment faire pour passer à la méthode read une variable par référence dont le type n'est pas connu à l'avance. (par référence car la méthode read doit modifier cette variable )

    merci d'avance.

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 175
    Points : 25 116
    Points
    25 116
    Par défaut
    ce n'est pas forcément simple

    une des possibilité c'est de faire une classe puis de faire une classe pas type qui hérite de la première avec une surcharge sur la machin as byref-er
    le tout avec une interface et un constructeur de classe

    enfin je ne sais pas si ca va dans ton cas car j'ai pas lu le code (il y a une balise code qui permet que ca soit plus attrayant)

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Gérant
    Inscrit en
    Août 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    merci pour ta réponse sperot21

    j'ai un peu avancé en utilisant les types 'generic' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    Public Class TFileType(Of type)
        Private TypeSize As Integer
        Private fs As FileStream
        Private v As type
        Public Sub New(ByVal FileName As String)
            TypeSize = Len(v)
            fs = New FileStream(FileName, FileMode.Open, FileAccess.ReadWrite)
        End Sub
        Public Sub free()
            fs.Close()
        End Sub
        Public Sub seek(ByVal index As Integer)
            fs.Position = index * TypeSize
        End Sub
        Public Function eof() As Boolean
            Return (fs.Position = fs.Length)
        End Function
        Function FileSize() As Integer
            Return fs.Length \ TypeSize
        End Function
     
        Function read(ByRef Buffer As type) As Integer
            Return fs.Read(Buffer, 0, TypeSize)
        End Function
        Public Sub write(ByRef Buffer As type)
            fs.Write(Buffer, 0, TypeSize)
        End Sub
     
    End Class
    j'instancie de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
                Dim fa As New TFileType(Of TArticle)(CheminFichierArticle)
    maintenant le problème est le suivant : comment lire ou écrire ma variable buffer dans le FileStream qui je crois ne peut lire ou écrire que des tableaux de Byte ou de Char. ( le compilateur refuse de faire la conversion TArticle vers tableau of Byte)
    je programme habituellement en Delphi et dans ce cas précis j'aurais utilisé des pointeurs, mais il semble que les pointeurs n'existent pas en VB.NET.

    des suggestions ?

    merci.

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Gérant
    Inscrit en
    Août 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut une solution possible mais pas top
    une solution possible mais pas très élégante à mon gout car la classe doit gérer d'avance tous les types possibles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    Imports System.IO
     
    Public Class TFileType(Of type)
        Private TypeSize As Integer
        Private fs As FileStream
        Private BinReader As BinaryReader
        Private BinWriter As BinaryWriter
        Private v As type
        Public Property article()
            Get
                Dim art As TArticle
                With art
                    .codbar1 = BinReader.ReadInt32
                    .codbar2 = BinReader.ReadInt32
                    .LongueurChaine = BinReader.ReadByte
                    .nom = BinReader.ReadChars(30)
                    .nom = ModifieAccentChaine(.nom.Substring(0, .LongueurChaine))
                    .famille = BinReader.ReadByte
                    .remise = BinReader.ReadByte
                    .prix = BinReader.ReadInt32
                    .actif = BinReader.ReadByte
                End With
                Return art
            End Get
            Set(ByVal value)
                Dim TabChar(29) As Char
                With value
                    BinWriter.Write(.codbar1)
                    BinWriter.Write(.codbar2)
                    BinWriter.Write(.LongueurChaine)
                    TabChar = .nom
                    BinWriter.Write(TabChar)
                    BinWriter.Write(.famille)
                    BinWriter.Write(.remise)
                    BinWriter.Write(.prix)
                    BinWriter.Write(.actif)
                End With
            End Set
        End Property
        Public Sub New(ByVal FileName As String)
            TypeSize = Len(v)
            fs = New FileStream(FileName, FileMode.Open, FileAccess.ReadWrite)
            BinReader = New BinaryReader(fs)
            BinWriter = New BinaryWriter(fs)
        End Sub
        Public Sub free()
            BinReader.Close()
            BinWriter.Close()
            fs.Close()
        End Sub
        Public Sub seek(ByVal index As Integer)
            fs.Position = index * TypeSize
        End Sub
        Public Function eof() As Boolean
            Return (fs.Position = fs.Length)
        End Function
        Function FileSize() As Integer
            Return fs.Length \ TypeSize
        End Function
    End Class
    utilisé de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Dim fa As New TFileType(Of TArticle)(CheminFichierArticle)
     
    dim article as TArticle=CType(fa.article, TArticle)
    si quelqu'un à une meilleur idée, je suis preneur

    merci.

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Gérant
    Inscrit en
    Août 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France, Vosges (Lorraine)

    Informations professionnelles :
    Activité : Gérant

    Informations forums :
    Inscription : Août 2007
    Messages : 4
    Points : 1
    Points
    1
    Par défaut peut être la meilleur solution :
    en lisant l'excellent cours de Philippe Lasserre sur le site j'ai vu que l'on pouvait surcharger les méthodes Ctype d'une structure. C'est ce que j'ai fait : ( ajout de Byte() -> TArticle et TArticle -> Byte() )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    Public Structure TArticle
        Dim codbar1 As Integer
        Dim codbar2 As Integer
        Dim LongueurChaine As Byte
        <VBFixedString(30)> Dim nom As String
        Dim famille As Byte
        Dim remise As Byte
        Dim prix As Integer
        Dim actif As Byte 'en principe boolean mais prend 2 octets en VB
        Public Shared Widening Operator CType(ByVal buffer As Byte()) As TArticle
            Dim art As New TArticle
            With art
                .codbar1 = bufferToInteger(buffer(0), buffer(1), buffer(2), buffer(3))
                .codbar2 = bufferToInteger(buffer(4), buffer(5), buffer(6), buffer(7))
                .LongueurChaine = buffer(8)
                .nom = bufferToCharTab(9, 30, buffer)
                .famille = buffer(39)
                .remise = buffer(40)
                .prix = bufferToInteger(buffer(41), buffer(42), buffer(43), buffer(44))
                .actif = buffer(45)
            End With
            Return art
        End Operator
        Public Shared Widening Operator CType(ByVal art As TArticle) As Byte()
            Dim buffer(45) As Byte
            With art
                IntegerToBuffer(.codbar1, 0, buffer)
                IntegerToBuffer(.codbar2, 4, buffer)
                buffer(8) = .LongueurChaine
                CharTabToBuffer(9, 30, .nom, buffer)
                buffer(39) = .famille
                buffer(40) = .remise
                IntegerToBuffer(.prix, 41, buffer)
                buffer(45) = .actif
            End With
            Return buffer
        End Operator
    End Structure
    j'ai utilisé les fonctions et procédures suivantes pour les conversions : (je pense qu'elles peuvent être améliorées)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
        Public Function bufferToInteger(ByVal b1 As Byte, ByVal b2 As Byte, ByVal b3 As Byte, ByVal b4 As Byte) As Integer
            Dim res As Integer = b4
            res = (res << 8) + b3
            res = (res << 8) + b2
            res = (res << 8) + b1
            Return res
        End Function
        Public Sub IntegerToBuffer(ByVal i As Integer, ByVal deb As Byte, ByRef buffer() As Byte)
            buffer(deb) = CByte(i Mod 256)
            i = i >> 8
            buffer(deb + 1) = CByte(i Mod 256)
            i = i >> 8
            buffer(deb + 2) = CByte(i Mod 256)
            i = i >> 8
            buffer(deb + 3) = CByte(i Mod 256)
        End Sub
     
        Public Sub CharTabToBuffer(ByVal deb As Byte, ByVal count As Byte, ByRef TabChar() As Char, ByRef buffer() As Byte)
            For i As Integer = 0 To count - 1
                buffer(deb + i) = CByte(Asc(TabChar(i)))
            Next i
        End Sub
    voici le code complet de la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    Imports System.IO
     
    Public Class TFileType(Of type)
        Private TypeSize As Integer
        Private fs As FileStream
        Private v As type
        Public Sub New(ByVal FileName As String)
            TypeSize = Len(v)
            fs = New FileStream(FileName, FileMode.Open, FileAccess.ReadWrite)
        End Sub
        Public Sub free()
            fs.Close()
        End Sub
        Public Sub seek(ByVal index As Integer)
            fs.Position = index * TypeSize
        End Sub
        Public Function eof() As Boolean
            Return (fs.Position = fs.Length)
        End Function
        Function FileSize() As Integer
            Return fs.Length \ TypeSize
        End Function
        Function read() As Byte()
            Dim buffer(TypeSize) As Byte
            fs.Read(buffer, 0, TypeSize)
            Return buffer
        End Function
        Sub write(ByVal buffer() As Byte)
            fs.Write(buffer, 0, TypeSize)
        End Sub
    End Class
    instancié de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
                Dim fa As New TFileType(Of TArticle)(CheminFichierArticle)
    pour la lecture d'une variable de type TArticle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    dim article as New TArticle
    article = CType(fa.read, TArticle)
    pour l'écriture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fa.write(CType(article, byte()))
    merci pour tout commentaire qui permettrait d'améliorer cette solution.

Discussions similaires

  1. Réponses: 6
    Dernier message: 21/05/2010, 17h40
  2. Réponses: 9
    Dernier message: 08/07/2009, 17h10
  3. Réponses: 1
    Dernier message: 12/06/2008, 20h07
  4. Réponses: 4
    Dernier message: 29/08/2006, 14h52
  5. [C#][Débutant] Comment gerer des datas dans une form
    Par Cazaux-Moutou-Philippe dans le forum Windows Forms
    Réponses: 4
    Dernier message: 30/04/2006, 00h10

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