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 :

Déterminer un type à partir d'un generic


Sujet :

VB.NET

  1. #1
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut Déterminer un type à partir d'un generic
    Bonjour à tous,

    J'ai un ensemble de types qui obéissent au schéma suivant :
    - une classe définissant le type à proprement parler
    - une classe « wrapper » offrant une interface en lecture seule pour un objet dudit type
    - une structure définissant les propriétés du type

    Par exemple, pour un type Company, on a les 3 classes suivantes :

    Company
    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
    Public Class Company
        Private _properties As CompanyPropertySet
     
        Public Sub New(ByVal properties As CompanyPropertySet)
            Me.properties = properties
        End Sub
     
        Public Property properties As CompanyPropertySet
            Get
                Return _properties
            End Get
            Set(ByVal value As CompanyPropertySet)
                'code garantissant les invariants de la classe
                '...
     
                _properties = value
            End Set
        End Property
    End Class
    CompanyConstWrapper
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Public Class CompanyConstWrapper
        Private _company As Company
     
        Public Sub New(ByRef company As Company)
            _company = company
        End Sub
     
        Public ReadOnly Property properties As CompanyPropertySet
            Get
                Return _company.properties
            End Get
        End Property
    End Class
    CompanyPropertySet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Public Structure CompanyPropertySet
        Public id As UInteger
        Public reference As String
        Public name As String
    End Structure
    Étant donné que ce schéma est extrêmement redondant, j'aimerais naturellement le factoriser.
    J'aimerais pour ce faire créer un type générique ConstWrapper(Of …), pour ne pas avoir à réécrire une classe XxxConstWrapper pour chaque type de ce genre.
    Ce type générique ressemblerait à cela (ce code ne compile pas) :
    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
    Public Interface IConstWrappable(Of PropertySet)
        ReadOnly Property properties As PropertySet
    End Interface
     
    Public Class ConstWrapper(Of T As IConstWrappable(Of T.PropertySet))
        Private _obj As T
     
        Public Sub New(ByRef obj As T)
            _obj = obj
        End Sub
     
        Public ReadOnly Property properties As T.PropertySet
            Get
                Return _obj.properties
            End Get
        End Property
    End Class
    Ma question est la suivante : comment faire pour déterminer CompanyPropertySet (T.PropertySet dans le pseudocode du generic) à partir de Company (T dans le pseudocode du generic) ?
    J'aimerais pouvoir utiliser mon type générique comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim constCompany as ConstWrapper(Of Company)
    sachant que ConstWrapper doit bien entendu pouvoir être configuré avec d'autres types (Employee, Contract, etc.).

    Merci !
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  2. #2
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Salut,

    si j'ai bien compris ton problème, tu peux t'inspirer de ce thread.
    Regarde plutôt le/les derniers messages, là où ma classe DAL générique marchait.
    J’ai des questions à toutes vos réponses!

  3. #3
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Bonjour -N4w4k-,

    Je ne pense pas que l'on parle de la même chose .
    Merci tout de même !
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  4. #4
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    J'aimerais pouvoir utiliser mon type générique comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim constCompany as ConstWrapper(Of Company)
    sachant que ConstWrapper doit bien entendu pouvoir être configuré avec d'autres types (Employee, Contract, etc.).
    Ce n'était pas le sujet du thread mais ma classe DAL générique pouvait être instancier à partir de différents objets ce qui me permettait d'accéder à mes tables produit, user, etc. avec l'unique classe DAL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Public Class DALClass(Of T As Class)
    '...
    La classe s'adaptait à l'entité que je lui passais en paramètre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim roles As New DALClass(Of Role)
    Dim users As New DALClass(Of User)
    J’ai des questions à toutes vos réponses!

  5. #5
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Oui, ça c'est le cas de base pour l'utilisation d'un generic.
    Ce dont j'ai besoin, c'est de pouvoir déduire un second type à partir du type qui est passé en paramètre.

    J'aimerais que ConstWrapper(Of Company) génère une propriété readonly de type CompanyPropertySet. Et je voudrais qu'il déduise ce type à partir de Company.

    À l'avenir, j'aurais deux nouveaux type Employee et EmployeePropertySet. J'aimerais que ConstWrapper(Of Employee) génère une propriété readonly de type EmployeePropertySet.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  6. #6
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Ok, je comprend. Du coup je sais pas
    J’ai des questions à toutes vos réponses!

  7. #7
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Ma question est la suivante : comment faire pour déterminer CompanyPropertySet (T.PropertySet dans le pseudocode du generic) à partir de Company (T dans le pseudocode du generic) ?
    A l'aide d'interfaces??
    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
    Interface Objet
        Property Propriete As Propriete
    End Interface
     
    Interface Propriete
    End Interface
     
    Class ConstWrapper(Of T As Objet)
     
        Property Objet As Objet
        ReadOnly Property Propriete As Propriete
            Get
                Return Objet.Propriete
            End Get
        End Property
     
        Sub New(ByVal obj As Objet)
            Objet = obj
        End Sub
     
    End Class
    J’ai des questions à toutes vos réponses!

  8. #8
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    A l'aide des interfaces, oui. Notamment une interface IHasPropertySet(Of TPropertySet), qui serait implémentée à la fois par Company et ConstWrapper(Of TPropertySet).
    En fait une telle interface élimine le besoin de ConstWrapper tel qu'il a été présenté : si l'on veut un accès en lecture seule, il suffit de renvoyer company sous la forme d'un IHasPropertySet(Of CompanyPropertySet) plutôt que sous la forme d'un Company.
    Enfin si vous voulez du code ce sera en C#.

  9. #9
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    @-N4w4k-
    Bien essayé, mais avec cette solution je me retrouve avec un typage faible sur les propriétés des mes objets, d'autant plus que l'interface Propriete ne définit aucune contrainte.
    Au final je pourrai assigner un EmployeePropertySet à un objet Company sans que le compilo ne me dise rien. Ça fait une bombe à retardement à l'exécution, ce qui n'est pas top.

    @DonQuiche
    A l'aide des interfaces, oui. Notamment une interface IHasPropertySet(Of TPropertySet), qui serait implémentée à la fois par Company et ConstWrapper(Of TPropertySet).
    Le ConstWrapper contient une référence vers un objet Company, non directement vers un objet CompanyPropertySet . La nuance est importante, car lorsque les propriétés de l'objet Company sont modifiés, les propriétés du ConstWrapper doivent l'être aussi.
    En fait une telle interface élimine le besoin de ConstWrapper tel qu'il a été présenté : si l'on veut un accès en lecture seule, il suffit de renvoyer company sous la forme d'un IHasPropertySet(Of CompanyPropertySet) plutôt que sous la forme d'un Company.
    Hélas, dans ce cas il suffit d'un simple cast de IHasPropertySet(Of CompanyPropertySet) vers Company pour avoir l'accès en écriture.

    Mais de toute façon cela ne résout pas le problème, qui est que je souhaite pouvoir écrire ConstWrapper(Of Company), et non ConstWrapper(Of Company, CompanyPropertySet) qui est redondant.

    Merci tout de même pour vos réponses .
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  10. #10
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Le ConstWrapper contient une référence vers un objet Company, non directement vers un objet CompanyPropertySet . La nuance est importante, car lorsque les propriétés de l'objet Company sont modifiés, les propriétés du ConstWrapper doivent l'être aussi.
    Dans ton exemple le CompanyConstWrapper n'exposait que PropertySet. Avec le générique que j'ai proposé il suffit de passer en argument du constructeur de ConstWrapper(Of T) un objet du type IHasPropertySet(Of T) plutôt qu'un objet Company. Or, Company implémente IHasPropertySet(Of T).

    Réfléchis-y mais c'est logique : tu veux offrir un wrapper en lecture seule. Donc cela implique que l'object initial et le wrapper exposent tous deux des méthodes similaires, autrement qu'ils pourraient tous deux implémenter une même interface. Et donc tu peux bâtir un wrapper générique comme celui que j'ai proposé : non pas un IWrapper(Of TWrapped) mais un wrapper implémentant la même interface que l'objet wrappé.

    De la même façon, on n'écrit pas un ReadOnlyListWrapper(Of TList) mais un ReadOnlyListWrapper(Of TItem), prenant en argument du constructeur un IList(Of TItem). Si en plus IList avait une interface de base IReadOnlyList, tu te retrouverais dans le cadre de ce que je propose, où IList et ReadOnlyListWrapper implémenteraient la même interface de base IReadOnlyLIst.

    Hélas, dans ce cas il suffit d'un simple cast de IHasPropertySet(Of CompanyPropertySet) vers Company pour avoir l'accès en écriture.
    Bien sur mais est-ce important ? Les consommateurs de l'API sont-ils des criminels dont il faut se protéger ou simplement des développeurs qu'il faut guider dans la bonne façon d'utiliser l'API ? Par exemple en leur exposant une interface en lecture seule plutôt que directement l'objet.

  11. #11
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    si vous voulez du code ce sera en C#.
    Moi je veux bien! J'ai un peu de mal à interpréter vos propos, je pense que ça serait plus clair avec un exemple.. Merci
    J’ai des questions à toutes vos réponses!

  12. #12
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Pas de souci.
    Donc, aujourd'hui, Company et CompanyConstWrapper ont tous deux une unique propriété qui renvoie un CompanyPropertySet.

    Autrement dit on peut créer une interface ainsi :
    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 interface IHasPropertySet<TSet> 
    {
        TSet Properties { get; }
    }
     
    public class Company : IHasPropertySet<CompanyPropertySet>
    {
        private readonly CompanyPropertySet _properties;
     
        public Company(CompanyPropertySet properties)
        {
             _properties = properties;
        }
     
        public TSet Properties
        {
             get { return _properties; }
        }
    }
     
    public ReadOnlyWrapper<TSet> : IHasPropertySet<TSet>
    {
        private readonly IHasPropertySet<TSet> _wrapped;
     
        public ReadOnlyWrapper(IHasPropertySet<TSet> wrapped)
        {
             _wrapped = wrapped;
        }
     
        public TSet Properties
        {
             get { return _wrapped.Properties; }
        }
    }
     
    // Un exemple d'utilisation
    Company company = new Company(new CompanyPropertySet());
    var wrapper = new ReadOnlyWrapper<CompanyPropertySet>(company);
    Debug.Assert(wrapper.Properties == company.Properties);

  13. #13
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Merci. J'en ai profité pour le convertir en VB.NET:
    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
    'IHasPropertySet(Of TSet)
    Public Interface IHasPropertySet(Of TSet)
        ReadOnly Property Properties() As TSet
    End Interface
     
    'CompanyPropertySet
    Public Class CompanyPropertySet
    End Class
     
    'Company
    Public Class Company
        Implements IHasPropertySet(Of CompanyPropertySet)
     
        Private ReadOnly _properties As CompanyPropertySet
     
        Public Sub New(ByVal properties As CompanyPropertySet)
            _properties = properties
        End Sub
     
        Public ReadOnly Property Properties As CompanyPropertySet Implements IHasPropertySet(Of CompanyPropertySet).Properties
            Get
                Return _properties
            End Get
        End Property
     
    End Class
     
    'ReadOnlyWrapper(Of TSet)
    Public Class ReadOnlyWrapper(Of TSet)
        Implements IHasPropertySet(Of TSet)
     
        Private ReadOnly _wrapped As IHasPropertySet(Of TSet)
     
        Public Sub New(ByVal wrapped As IHasPropertySet(Of TSet))
            _wrapped = wrapped
        End Sub
     
        Public ReadOnly Property Properties As TSet Implements IHasPropertySet(Of TSet).Properties
            Get
                Return _wrapped.Properties
            End Get
        End Property
     
    End Class
     
    Module Test
     
        Sub Main()
            ' Un exemple d'utilisation
            Dim company As New Company(New CompanyPropertySet())
            Dim wrapper As New ReadOnlyWrapper(Of CompanyPropertySet)(company)
            Debug.Assert(wrapper.Properties.Equals(company.Properties))
     
        End Sub
     
    End Module
    Donc si j'ai bien compris l'intérêt du ReadOnlyWrapper c'est de pouvoir priver le consommateur de l'API des classes Company et CompanyPropertySet, afin de l’empêcher d'assigner un EmployeePropertySet à un objet Company par exemple (je suis encore pas certain d'avoir compris le sujet du thread ^^). Si c'est ça c'est bien vu
    Est ce que c'est un design pattern connu et reconnu?
    J’ai des questions à toutes vos réponses!

  14. #14
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par -N4w4k- Voir le message
    Donc si j'ai bien compris l'intérêt du ReadOnlyWrapper c'est de pouvoir priver le consommateur de l'API des classes Company et CompanyPropertySet, afin de l’empêcher d'assigner un EmployeePropertySet à un objet Company par exemple (je suis encore pas certain d'avoir compris le sujet du thread ^^).
    L'exemple que tu fournis est un peu perturbant parce que Company ne permettrait de toute façon pas qu'on lui assigne un EmployeePropertySet. en revanche la description du but est correcte : il s'agit de priver le consommateur de certaines API de Company, notamment celles qui pourrait le modifier.

    Est ce que c'est un design pattern connu et reconnu?
    Au vu de l'intention (restreindre l'accès à l'objet wrappé), c'est un proxy, même si en général la restriction d'accès est plutôt basée sur des permissions systèmes ou une gestion des ressources.

    Maintenant, on doit peut-être aussi tenir compte du fait que le wrapper et le wrappé partagent la même interface. En règle générale, les design patterns sont assez lâches sur l'implémentation exacte mais il y a des usages répandus. En général, un proxy ne ressemble pas au wrappé. C'est en revanche fréquent, et presque implicite selon la défintion, avec le pattern décorateur (un wrapper qui réplique l'interface du wrappé et l'enrichit de nouvelles reponsabilités). Alors disons que c'est un proxy à l'odeur de décorateur. Peut-être devrait-on simplement étendre la définition du décorateur ou créer un pattern spécifique.

    Quant à savoir si c'est commun... On trouve typiquement des wrappers en lecture seule pour les structures de données dans plusieurs langages. C'est par exemple le cas en dotnet avec ReadOnlyList, ReadOnlyDictionary, etc. Et si tu recherches les types contenant le mot "internal" dans ILSpy, Reflector ou autres, tu trouveras également quelques types internes dans la clr qui ont des wrappers publics suivant le même pattern. Cela étant dit je pense que le besoin lui-même, restreindre par la force l'accès à des méthodes publiques, est questionnable : dotnet gagne peu à avoir cette ReadOnlyList et aurait davantage besoin de IReadableList et IReadableCollection (en fait, IList devrait plutôt être RO et IWriteableList hériter de IList). J'avais déjà soulevé cette question dans le post précédent. C'est sans doute cela qui fait que ce pattern n'est pas si répandu que ça.

  15. #15
    Membre éclairé Avatar de -N4w4k-
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2011
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2011
    Messages : 545
    Points : 801
    Points
    801
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    L'exemple que tu fournis est un peu perturbant parce que Company ne permettrait de toute façon pas qu'on lui assigne un EmployeePropertySet.
    En effet la description que j'ai donnée ne collait pas avec l'exemple..

    Merci pour l'explication de ce pattern. Je me sert trop de l'héritage et pas assez des interfaces, du coup je passe à coté de plein de pattern et la conception de mes applications de doit pas être au top
    J’ai des questions à toutes vos réponses!

  16. #16
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    @DonQuiche
    Tout d'abord, un grand merci pour ton coup de main. Je pense que je pourrai difficilement faire mieux en VB.NET, donc j'ai retenu ta solution . Je passe le thread en résolu.

    Mais puisque j'aime bien papoter, je vais tout de même me faire le plaisir de pinailler un petit peu .
    Personnellement, je trouve l'écriture ReadOnlyWrapper(Of Xxx) plus intuitive. C'est bien l'accès de Xxx que l'on souhaite restreindre. XxxPropertySet n'est qu'un artifice pour permettre l'écriture de ce Wrapper.

    Citation Envoyé par DonQuiche Voir le message
    Bien sur mais est-ce important ? Les consommateurs de l'API sont-ils des criminels dont il faut se protéger ou simplement des développeurs qu'il faut guider dans la bonne façon d'utiliser l'API ? Par exemple en leur exposant une interface en lecture seule plutôt que directement l'objet.
    Comme le disent les Pythoneux, nous sommes effectivement entre adultes consentants. Mais un certain gourou du C++ (Scott Meyers pour ne pas le citer) érige en principe cette idée : « Make Interfaces Easy to Use Correctly and Hard to Use Incorrectly ». Il est tellement facile d'écrire un cast que l'on donne à croire à l'utilisateur de l'API qu'il s'agit d'un mode d'utilisation normal ou « pas si grave que ça ».
    Je ne prends aucunement les autres développeurs pour des idiots. Ça nous arrive à tous d'être dans le rush et de conclure que dès que ça compile, c'est validé ou presque.

    @-N4w4k-
    Pour information, en C++ (un des langages utilisés pour l'implémentation des design patterns dans le bouquin du Gang of Four, créateurs des design patterns originaux), il existe le mot-clé « const » qui permet de restreindre en lecture seule n'importe quel objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Company company("Ma compagnie");
    const Company& company_const_reference = company; //référence vers un objet Company constant
    Cela explique peut-être aussi le fait qu'un wrapper en lecture seul ne fasse pas partie des design patterns récurrents.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  17. #17
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    @Florian
    C'est vrai que dans ce cas précis la syntaxe que tu désirais serait préférable si elle était possible. Quant à ton second point, c'est une question subjective. Un cast me semble rendre les choses suffisamment "difficiles" (je suis feignant et ce genre de détail m'interpelle) mais il est vrai que des exemples concrets abondent dans ton sens, cf. The old new thing :
    - Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?
    - Apparently anyone.


    Enfin, bien vu sur le "const" C++ et son influence possible sur l'absence de ce design pattern.

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

Discussions similaires

  1. [VB.NET]Comment obtenir un type à partir d'un string?
    Par NicolasJolet dans le forum VB.NET
    Réponses: 2
    Dernier message: 24/02/2006, 15h46
  2. Réponses: 1
    Dernier message: 14/02/2006, 20h22
  3. Impossible de déterminer le type
    Par Aloui dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 13/12/2005, 11h16
  4. Déterminer le type d'une class dérivée
    Par LDDL dans le forum MFC
    Réponses: 3
    Dernier message: 10/12/2004, 17h36
  5. [struts] déterminer le type Mime d'un fichier
    Par k4eve dans le forum Struts 1
    Réponses: 4
    Dernier message: 14/06/2004, 10h28

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