Partage
  • Partager sur Facebook
  • Partager sur Twitter

Une histoire de mère et d'enfants

Class et list, tout une histoire

    5 juillet 2021 à 19:17:18

    Bonjour,

    J'essai de me dépatouiller d'un soucis sans succès.

    j'ai le cas suivant, une classe mère contient une liste d'éléments issues d'une autre classe contenant des enfants.

    Classes "Avt" (mère) possèdent 2 enfants "AvtC" et "AvtA"

    Class "ElementBase" (mère) possèdent 2 enfants "ElementC" et "ElementA"

    En fait, dans "la réalité" lea classe AvtC contient une liste d'éléments "ElementC" et la classe AvtA contient une liste d'éléments "ElementA"

    Mais pour éviter plein de select case, if etc, lors de l'exploitation, voulant éviter de faire 2 fonctions traitant les données dans un cas les "A" et l'autre les "C", une cinquantaine de ligne quasi identique, avec des différences sur des fonctions présente dans l'un pas dans l'autre.

    j'ai donc remonté la liste dans la classe mère "Avt" qui contient donc une list(of Element Base), de ce fait j'ai des fonctions communes ( Ex : NbElement, comptant directement la liste)

    Mon soucis est lors que je veux accéder justement à cette liste, ou travailler dessus. je ne peux pas caster un list(of Classe Mère en classe enfant)

    j'ai essayé de passer par les IEnumerable, avec des ToList() etc.. bref c'est l'usine à gaz, je pense mal m'y prendre.

    J'espère avoir bien expliqué, j'ai encore la tête tout encombré.

    Merci de votre aide.

    Ci dessous une représentation épuré des classes

    Public Class ElementBase
        public Name as string
        
    
        Public Sub new(name as string)
            me.name=name
        end sub
    
    end Class
    
    Public Class ElementC
        inherits ElementBase
    
        Private ExtensionName as string
    
        public sub new(Name as string, specificName as string)
            mybase.new(name)
            me.ExtensionName = specificName
        end sub
    
    end Class
    Public Class ElementA
        inherits ElementBase
    
    
        public sub new(Name as string)
            mybase.new(name)
        end sub
    
    end Class
    
    
    Public Class AvtBase
    
        private LstElement as List(Of ElementBase)
    
        Public Function NbElement as integer
    
            return LstElement.count
    
        end function
    
    end Class
    
    Public Class AvtC
      inherits AvtBase    
    
        Public sub SpecificMethod_C As integer
        end sub
    end class
    
    Public Class AvtA
     inherits AvtBase
    
    
        Public sub SpecificMethod_A As String
        end sub
    
    end class



    • Partager sur Facebook
    • Partager sur Twitter
      6 juillet 2021 à 16:57:08

      Bonjour,

      Je pense que votre conception est un peu foireuse. En fait, je ne vois pas l'intérêt de placer la liste dans AvtBase.

      Placez une liste de ElementA dans AvtA et une liste de ElementC dans AvtC.

      Je pense que vous pouvez remplacer la classe AvtBase par une interface, IAvt par exemple. Par cette interface vous exposerez les méthodes nécessaires au traitement "commun" qui sera fait de ces deux classes.

      Ensuite, pas de casts à faire. 
      Imaginons deux liste d'objets, une liste d'objets A, et une liste d'objets B. A et B implémentent la même interface, IExempleInterface.

      Vous pouvez tout à fait faire quelques choses du genre : 

      Interface IExempleInterface
          Function doSmtg() As String
      End Interface
      
      Public Class A
          Implements IExempleInterface
      
          Public Function doSmtg() As String
              Return "un traitement quelconque"
          End Function
      End Class
      
      Public Class B
          Implements IExempleInterface
      
          Public Function doSmtg() As String
              Return "un autre traitement quelconque"
          End Function
      End Class
      
      Public Class ExempleExec
          Public Shared Sub Exemple(ByVal lesA As List(Of A), ByVal lesB As List(Of B))
              Dim lst As List(Of IExempleInterface) = New List(Of IExempleInterface)()
              lst.AddRange(lesA)
              lst.AddRange(lesB)
      
              For Each ex As IExempleInterface In lst
                  ex.doSmtg()
              Next
          End Sub
      End Class
      

      Si ce n'est pas clair, je vous propose de regarder des cours de programmation orienté objet sur youtube. Il y en a pleins de biens :)

      Vous pouvez aussi passer par des classes génériques, mais je ne suis pas sûr que cela soit ce que vous vouliez faire.

      -
      Edité par earp91 6 juillet 2021 à 17:08:21

      • Partager sur Facebook
      • Partager sur Twitter
        6 juillet 2021 à 17:58:31

        Bonjour,

        Je pense aussi que je m'y prends mal, justement à la base j'étais parti dans le placement des différents éléments dans chaque classe de type de Avt

        Sauf que je devais d'un côté retourner d'un côté la liste typé "ElementC" et de l'autre "ElementA"

        J'avais tenté de faire une interface (pas l'habitude) mais pareil, je dois typer mon retour. 

        nota : je ne peux pas avoir de mélange.

        j'essai d'expliquer un peu plus concrètement :

        Avt = Avancement 

        El = Element, dans chaque élément, j'ai des stades d'avancements(Nom, pourcentage du Stade(ce qu'il représente sur l'élément), Avancement du stade sous forme décimal), l'ensemble des stades d'un élément = 100%

        exemple : Element1 est divisé en 3 stades : début(15%), milieu(75%), fin(10%), c'est variable d'un élément à l'autre.

        dans un Avt, j'ai X élements.

        Dans les AvancementC j'ai des élémentC, dans les AvancementA, j'ai des élementA.

        Les elementC et elementA ont des choses en communs, comme les stades, un nom. mais l'élémentC à un élément supplémentaire : étage.

        Exemple AvancementC

        BAT1 - RDC : début(15%), milieu(75%), fin(10%)

        BAT1 - Etage1 : début(10%), milieu(85%), fin(5%)

        BAT2 - RDC : début(15%), milieu(75%), fin(10%)

        BAT2 - Etage1 : début(10%), milieu(85%), fin(5%)

        BAT2 - Etage3 : Tout(95%), finition(5%)

        Exemple AvancementA :

        Cloture : Installation(90%), Controle(10%)

        Chaussée : Installation(10%), coulage(75%), bordure(15%)

        J'ai donc lors de l'impression d'une partie d'un document, l'envoi d'un "AvancementC" ou "AvancementA" pour réaliser un tableau, dans tout les cas je compte mes éléments, je les parcours.

        J'ai limité ici un peu les infos, car j'ai aussi sur les éléments, des champs supplémentaires et différents.

        J'espère avoir plus clairement expliqué les choses.

        earp91 a écrit:

        Bonjour,

        Je pense que votre conception est un peu foireuse. En fait, je ne vois pas l'intérêt de placer la liste dans AvtBase.

        Placez une liste de ElementA dans AvtA et une liste de ElementC dans AvtC.

        Je pense que vous pouvez remplacer la classe AvtBase par une interface, IAvt par exemple. Par cette interface vous exposerez les méthodes nécessaires au traitement "commun" qui sera fait de ces deux classes.

        Ensuite, pas de casts à faire. 
        Imaginons deux liste d'objets, une liste d'objets A, et une liste d'objets B. A et B implémentent la même interface, IExempleInterface.

        Vous pouvez tout à fait faire quelques choses du genre : 

        Interface IExempleInterface
            Function doSmtg() As String
        End Interface
        
        Public Class A
            Implements IExempleInterface
        
            Public Function doSmtg() As String
                Return "un traitement quelconque"
            End Function
        End Class
        
        Public Class B
            Implements IExempleInterface
        
            Public Function doSmtg() As String
                Return "un autre traitement quelconque"
            End Function
        End Class
        
        Public Class ExempleExec
            Public Shared Sub Exemple(ByVal lesA As List(Of A), ByVal lesB As List(Of B))
                Dim lst As List(Of IExempleInterface) = New List(Of IExempleInterface)()
                lst.AddRange(lesA)
                lst.AddRange(lesB)
        
                For Each ex As IExempleInterface In lst
                    ex.doSmtg()
                Next
            End Sub
        End Class
        

        Si ce n'est pas clair, je vous propose de regarder des cours de programmation orienté objet sur youtube. Il y en a pleins de biens :)

        Vous pouvez aussi passer par des classes génériques, mais je ne suis pas sûr que cela soit ce que vous vouliez faire.

        -
        Edité par earp91 il y a environ 1 heure



        • Partager sur Facebook
        • Partager sur Twitter
          8 juillet 2021 à 11:56:22

          Bonjour,
          Il y a une chose que je ne comprends pas.
          Vous dites "dans chaque élément, j'ai des stades d'avancements " et "dans un Avt, j'ai X élements"
          J'ai du mal à comprendre la hierarchie de vos classes.
          Cela représenterait un cycle de référence infini.


          Maintenant, si je m'en tiens à votre exemple de fin, voilà la construction de classe que j'utiliserais

          - Soit
          Imports System
          Imports System.Collections.Generic
          Imports System.Linq
          Imports System.Text
          Imports System.Threading.Tasks
          
          Namespace Subset
              Public Class StadeAvancement
                  Private designation As String
                  Private pourcentageAvancement As Integer
          
                  Public ReadOnly Property Description As String
                      Get
                          Return String.Format("{0}({1}%)", designation, pourcentageAvancement)
                      End Get
                  End Property
              End Class
          
              Interface IAvanceeChantier
                  Sub PrintDescription()
              End Interface
          
              Public Class AvanceeChantierClassique
                  Implements IAvanceeChantier
          
                  Public designationChantier As String
                  Public stadesAvancements As List(Of StadeAvancement)
          
                  Public Sub PrintDescription()
                      Console.WriteLine(String.Format("{0} : {1}", designationChantier, String.Join(",", stadesAvancements.[Select](Function(p) p.Description))))
                  End Sub
              End Class
          
              Public Class AvanceeChantierAEtages
                  Implements IAvanceeChantier
          
                  Private chantier As AvanceeChantierClassique
                  Private designationEtage As String
          
                  Public Sub PrintDescription()
                      Console.WriteLine(String.Format("{0} - {1} : {2}", chantier.designationChantier, designationEtage, String.Join(",", chantier.stadesAvancements.[Select](Function(p) p.Description))))
                  End Sub
              End Class
          
              Public Class Exemple
                  Private Shared Sub PrintTousLesChantiers(ByVal desChantiersClassiques As AvanceeChantierClassique, ByVal desChantiersAEtages As AvanceeChantierAEtages)
                      Dim lesChantiers As List(Of IAvanceeChantier) = New List(Of IAvanceeChantier)()
                      lesChantiers.Add(desChantiersClassiques)
                      lesChantiers.Add(desChantiersAEtages)
          
                      For Each chantier As IAvanceeChantier In lesChantiers
                          chantier.PrintDescription()
                      Next
                  End Sub
              End Class
          End Namespace
          
          - Ou bien
          Imports System
          Imports System.Collections.Generic
          Imports System.Linq
          Imports System.Text
          Imports System.Threading.Tasks
          
          Namespace Exemple
              Public Class StadeAvancement
                  Private designation As String
                  Private pourcentageAvancement As Integer
          
                  Public ReadOnly Property Description As String
                      Get
                          Return String.Format("{0}({1}%)", designation, pourcentageAvancement)
                      End Get
                  End Property
              End Class
          
              Public Class AvanceeChantierClassique
                  Protected designationChantier As String
                  Protected stadesAvancements As List(Of StadeAvancement)
          
                  Public Overridable Sub PrintDescription()
                      Console.WriteLine(String.Format("{0} : {1}", designationChantier, String.Join(",", stadesAvancements.[Select](Function(p) p.Description))))
                  End Sub
              End Class
          
              Public Class AvanceeChantierAEtages
                  Inherits AvanceeChantierClassique
          
                  Private designationEtage As String
          
                  Public Overrides Sub PrintDescription()
                      Console.WriteLine(String.Format("{0} - {1} : {2}", designationChantier, designationEtage, String.Join(",", stadesAvancements.[Select](Function(p) p.Description))))
                  End Sub
              End Class
          
              Public Class Exemple
                  Private Shared Sub PrintTousLesChantiers(ByVal desChantiersClassiques As AvanceeChantierClassique, ByVal desChantiersAEtages As AvanceeChantierAEtages)
                      Dim lesChantiers As List(Of AvanceeChantierClassique) = New List(Of AvanceeChantierClassique)()
                      lesChantiers.Add(desChantiersClassiques)
                      lesChantiers.Add(desChantiersAEtages)
          
                      For Each chantier As AvanceeChantierClassique In lesChantiers
                          chantier.PrintDescription()
                      Next
                  End Sub
              End Class
          End Namespace
          



          -
          Edité par earp91 8 juillet 2021 à 13:11:28

          • Partager sur Facebook
          • Partager sur Twitter

          Une histoire de mère et d'enfants

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown