Si je retire les propriétés DTO des classes filles, cela fonctionne mais alors, je dois faire un cast dans le bon type si je veux avoir au propriété spécifique sous-jacente de chaque DTO.
J'aimerais ne pas avoir à faire de cast en fait.
Si je retire les propriétés DTO des classes filles, cela fonctionne mais alors, je dois faire un cast dans le bon type si je veux avoir au propriété spécifique sous-jacente de chaque DTO.
J'aimerais ne pas avoir à faire de cast en fait.
Ton cas est plus compliqué.
En fait je crois que ton problème vient du fait qu'il y a un double Polymorphisme.
En l’occurrence tu souhaites faire du polymorphisme sur ton DTO puisque tu veux mettre PromoDetailOwn dans un PromoDetail.
Donc pour faire ça, le DTO PromoDetailOwn doit hérité du DTO PromoDetail.
(Ou peut être que c'est déjà le cas?)
Dans ce cas (substituant),
[Edit] c'est plus subtil, Overrides substitue juste une définition : Seulement une méthode avec une séquence d'appel identique, Overloads surcharge une définition existante Donne une nouvelle méthode. [/Edit]
Non puisque le premier permet de surcharger (donne une méthode de plus), alors que le second occulte (cache les définitions d'une méthode (de même nom) de la classe parent - défini une nouvelle portée)
substituer, surcharger et occulter sont 3 notions différentes.
@Kropernic
Vu que le type change.
Peux-tu nous donner quelques info de plus parce que là, l'utilisation que tu fais de l'ensemble est un peu flou pour moi.
C'est effectivement déjà le cas.
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 Public Class PromoDetail Implements DtoBase Public Property Isnew As Boolean Implements DtoBase.Isnew Public Property Id As Integer 'PED_ID pour demo et PEO_ID pour ferme Public Property BuyingDepartment As BuyingDept Public Property Comment As String Public Property Note As String Public Property PriceReduction As Boolean Public Property Percentage As Decimal Private _listType As String Public ReadOnly Property ListType As String Get Return _listType End Get End Property Private _products As List(Of Product) Public Property Products As List(Of Product) Get Return _products End Get Set(value As List(Of Product)) _products = value If value.Count > 0 Then _listType = "INC" End If End Set End Property Private _productsOut As List(Of Product) Public Property ProductsOut As List(Of Product) Get Return _productsOut End Get Set(value As List(Of Product)) _productsOut = value If value.Count > 0 Then _listType = "EXC" End If End Set End Property Public Sub New(id As Integer, buyingDept As BuyingDept, comment As String, note As String, priceReduction As Boolean, percentage As Decimal) Me.Id = id Me.BuyingDepartment = buyingDept Me.Comment = comment Me.Note = note Me.PriceReduction = priceReduction Me.Percentage = percentage Me._listType = Nothing Me.Isnew = False End Sub End Class Public Class PromoDetailDemo Inherits PromoDetail Public Property CodeDemo As CodeDemo Public Property Vbn As String Public Sub New(id As Integer, buyingDept As BuyingDept, comment As String, note As String, priceReduction As Boolean, percentage As Decimal, codeDemo As CodeDemo, vbn As String) MyBase.New(id, buyingDept, comment, note, priceReduction, percentage) Me.CodeDemo = codeDemo Me.Vbn = vbn End Sub End Class Public Class PromoDetailOwn Inherits PromoDetail Public Property Department As Department Public Property Brand As Brand Public Property Seasons As List(Of Season) Public Property SeasonsRange As String Public Sub New(id As Integer, buyingDept As BuyingDept, comment As String, note As String, priceReduction As Boolean, percentage As Decimal, dept As Department, brand As Brand) MyBase.New(id, buyingDept, comment, note, priceReduction, percentage) Me.Department = dept Me.Brand = brand Me.SeasonsRange = "" End Sub End Class
Et bien, j'ai recopier ton cas de figure, et tout marche pour moi. Quand j'appelle monobjet de la classe fille, il ne voit qu'un DTO et c'est celui de la classe fille. et je n'ai aucune erreur.
Et j'ai juste mis un Overloads sur la porpriété fille :
CLASSE + DTO :
UTILISATION :
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 Public Class ClasseMEre Public Property DTO As DTOMere Public Sub New(_DTO As DTOMere) DTO = _DTO End Sub End Class Public Class ClasseFille Inherits ClasseMEre Public Overloads Property DTO As DTOFille Public Sub New(_DTO As DTOFille) MyBase.New(_DTO) End Sub End Class Public Class DTOMere Public NomFamille As String Public Sub New(ByVal _s As String) NomFamille = _s End Sub End Class Public Class DTOFille Inherits DTOMere Public Prenom As String Public Sub New(ByVal _s1 As String, ByVal _s2 As String) MyBase.New(_s1) Me.Prenom = _s2 End Sub End Class
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Private Sub MONTEST() Dim dt_temp As New DTOFille("Dikens", "Charles") Dim MonObj As New ClasseFille(dt_temp) MsgBox(MonObj.DTO.NomFamille) MsgBox(MonObj.DTO.Prenom) End Sub
J'ai donc remodifié mon code pour tester ta solution (j'avais fait tourner le truc en virant la propriété dto des classes filles et en castant à chaque utilisation).
Voici comment je l'utilise par exemple :
Et voici ce que cela donne au debug...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Dim dtd_id As Integer = CInt(dgvPromoDetailDemo.Rows(e.RowIndex).Cells("dgvcId").Value) Dim dtd As PROMO_ICT_BLL.PromoDetailDemo = Promo.GetDetailDemoById(dtd_id) sfd.FileName = "D-" & CType(dtd.DTO, PROMO_ICT_DTO.PromoDetailDemo).CodeDemo.Code & "-" & dtd.DTO.Percentage.ToString & ".xls"
EDIT
Et pour être complet, voici le code de la fonction GetDetailDemoById :
On voit bien qu'il y a deux propriété DTO dans l'objet et qu'il essaie apparemment d'accéder à celle qu'il ne faut pas (merci Murphy)...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Public Function GetDetailDemoById(dtd_id As Integer) As PromoDetailDemo Return New PromoDetailDemo((From d As PROMO_ICT_DTO.PromoDetailDemo In DTO.DetailsDemo Where d.Id = dtd_id Select d).FirstOrDefault) End Function
Erreur stupide de ma part, j'avais oublié d'instancié le DTO de la classe fille
Et là ça marche:
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 Public Class ClasseMEre Public Property DTO As DTOMere Public Sub New(_DTO As DTOMere) DTO = _DTO End Sub End Class Public Class ClasseFille Inherits ClasseMEre Public Overloads Property DTO As DTOFille Public Sub New(_DTO As DTOFille) MyBase.New(_DTO) DTO = _DTO 'J'AVAIS OUBLIE CA End Sub End Class
Merci pour la 2ème partie de code (cela a éclairci)
Pour passer ce cap, j'ai plutôt abordé les génériques
Mais j'ai un problème sur la méthode GetProducts (pour la définir dans la classe mère)
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 Public Class PromoDetail(Of T) Public Overridable Property DTO As T Public Sub New(d As T) Me.DTO = d End Sub 'Public Function GetProducts() As List(Of PROMO_ICT_DTO.Product) ' If Me.DTO.Products.Count > 0 Then ' Return Me.DTO.Products ' ElseIf Me.DTO.ProductsOut.Count > 0 Then ' Return Me.DTO.ProductsOut ' Else ' Return Nothing ' End If 'End Function End Class Public Class PromoDetailDemo Inherits PromoDetail(Of PROMO_ICT_DTO.PromoDetailDemo) Public Overrides Property DTO As PROMO_ICT_DTO.PromoDetailDemo Public Sub New(dtd As PROMO_ICT_DTO.PromoDetailDemo) MyBase.New(dtd) End Sub Public Function GetProducts() As List(Of PROMO_ICT_DTO.Product) If Me.DTO.Products.Count > 0 Then Return Me.DTO.Products ElseIf Me.DTO.ProductsOut.Count > 0 Then Return Me.DTO.ProductsOut Else Return Nothing End If End Function End Class Public Class PromoDetailOwn Inherits PromoDetail(Of PROMO_ICT_DTO.PromoDetailOwn) Public Overrides Property DTO As PROMO_ICT_DTO.PromoDetailOwn Public Sub New(dto As PROMO_ICT_DTO.PromoDetailOwn) MyBase.New(dto) End Sub Public Function GetProducts() As List(Of PROMO_ICT_DTO.Product) If Me.DTO.Products.Count > 0 Then Return Me.DTO.Products ElseIf Me.DTO.ProductsOut.Count > 0 Then Return Me.DTO.ProductsOut Else Return Nothing End If End Function End Class
Peux-tu voir si ainsi cela fait avancer ton problème ? (ou si je fais fausse route)
mactwist a répondu entre temps, du coup ma réponse n'est peut-être pas utile.
Ouais mais on a bien deux propriété alors...
Soit j'ai pas compris le polymorphisme (pas impossible, j'ai jamais eu de cours de POO), soit y a un souci.
Pour moi, le polymorphisme dans ce cas, c'est d'avoir avoir une propriété/méthode/fonction dans la classe mère qui dit A et d'avoir la "même" (ie qui possède le même nom) propriété/méthode/fonction dans la classe fille qui dit B.
Ici, si je comprends bien :
- la classe mère possède une propriété qui dit A
- la classe fille possède une propriété qui dit A et une autre propriété qui dit B
Pas moyen de faire en sorte d'en avoir qu'une seule ??
De mon point de vue le polymorphisme n'est pas aussi simple.
- Si il y a deux fonctions classe mere/fille qui s'appellent pareil, alors si tu déclares un objet mère, il utilisera celui de la mère, sinon celui de la fille.
Mais ça c'est de la réécriture.
- Le polymorphisme c'est de pouvoir mettre la propriété de la classe fille dans celui de la mère.
Ainsi dans la classe mère, si tu appelles cette fameuse fonction qui est récrites dans la classe fille , alors il appellera celui de la fille, car il sait que son objet est fille.
Hello Hervé !
Tes réponses ne sont jamais inutile. Tu apportes à chaque fois une autre manière de voir les choses et c'est toujours instructif !
Ici par contre, le simple fait de devoir répéter la méthode GetProducts dans les classes filles avec un code strictement identique me gêne vraiment trop que pour adopter cette approche.
D'ailleurs, c'est typiquement un cas d'héritage non ? Qu'est-ce qui t'as poussé vers les génériques dans ce cas-ci ??
Tu veux dire la possibilité de mettre une instance de la fille dans une variable de type mère ; alors le résultat sera la propriété/méthode de la fille seulement si elle est Overrides. Si elle est Overloads dans ce cas il appelle celle de la mère (ou il faut caster). (c'est une des différences dans l'utilisation des 2)
J'avoue ma définition n'était peut être pas tout à fait exacte.
Je n'ai utiliser le polymorphisme que pour une chose, donc je peux te donner mon exemple, mais il est un peu éloigné du tient.
J'ai une classe mère à MustInherits (donc on on ne peut pas déclarer un objet mère)
J'ai n classes filles qui héritent de la classe mère.
La classe mère a 4 fonctions publique (CRUD) create, update etc...
Donc prenons la fonction Save()
Je créer dans le même temps une fonction (mustoverride) SavedDervided dans la classe mère (qui n'est qu'un déclaration, cf ci dessous)
Du coup dans chacune des classes filles, je suis obligé de créer SavedDerived (grâce, ou a cause de mustoverride)
Save() fait ce qu'il a a faire avec les propriété de la classe mere puis appelle SavedDerived()
Du point de vue utilisation, quand je fais MonObjetFille.Save(), il se rends d'abord dans la classe mère, puis cherche la bonne classe fille et appelle le bon SaveDerived. Le polymorphisme me permet cela.
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 Public MustInherit Class ClasseMEre Public Sub Save() 'ici on fait ce qu'on veut avec les propriétés de la mere 'Puis on appelle le save de la classe fille SaveDerived() End Sub 'On oblige les classes fille a implémenter cette fonction Protected MustOverride Sub SaveDerived() End Class Public Class ClasseFille1 Inherits ClasseMEre 'Foncton invisible depuis l'extérieur Protected Overrides Sub SaveDerived() 'OPeration de sauvegarde spécifique End Sub End Class Public Class ClasseFille2 Inherits ClasseMEre Protected Overrides Sub SaveDerived() 'OPeration de sauvegarde End Sub End Class
Ca me permets de mettre dans Save() le code commun à toutes les classes fille (les règles métier), puis il va exécuter ce qui est spécifique dans SaveDerived de la bonne classe fille.
Je ne sais pas si c'est une utilisation normal... Mais ça ma permis de factoriser tout le code commun dans la classe mère, et mes classes filles ne possède que le spécifique.
Je te rassure, moi non plus je n'ai pas eu de cours. (j'apprend aussi à travers les discussions et en cherchant)
Je suis d'accord avec toi pour la répétition, mais avant d'aller plus loin, je voulais savoir si cela correspondait, afin que je ne perde pas trop de temps pour rien.
Je comptais voir comment faire sinon.
Pourquoi les génériques, parceque avec le polymorphisme tu ne changes pas le type normalement. [Edit=précision] je parle des méthodes que l'on substitues [/Edit]
Afin, après je ne suis pas expert en POO non plus, je ne connais donc pas tout.
Le problème, c'est que l'on ne trouve que des cas simples ou de base.
Ca veut dire qu'on ne devrait pas vouloir faire ce genre de truc ?? :-/
Je ne dis pas ça (vu que ton code est tout de même fonctionnel), j'ai simplement pensé faire autrement, cela ne veut pas dire que c'est mieux (de l'héritage et du générique ).
[Edit] A première vu, ca ne semble pas une bonne idée.
sinon (cela n'a rien à voir), que penses-tu d'écrire ta méthode comme ça ?
Je trouve plus lisible
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Public Function GetProducts() As List(Of PROMO_ICT_DTO.Product) If Me.DTO.Products.Count > 0 Then Return Me.DTO.Products If Me.DTO.ProductsOut.Count > 0 Then Return Me.DTO.ProductsOut Return Nothing End Function
Ben justement, cela m'a plus fait penser à du générique ou c'est seulement le type qui change (du genre List(of ...))
Du coup, pour finir avec les génériques, même si cela ne semble pas une bonne piste, je te livre l'approche.
Tu peux créer une seule classe PromoDetail(Of T) (plus de classe PromoDetailDemo et PromoDetailOwn)
Test d'utilisation par création directe (pas correct puisque les listes ne sont pas crées, mais pour test)
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 PromoDetail(Of T) Public Property DTO As Object ' As T aurait été mieux, mais impossible d'exploiter le DTO Public Sub New(d As T) Me.DTO = d End Sub Public Function GetProducts() As List(Of PROMO_ICT_DTO.Product) If Me.DTO.Products.Count > 0 Then Return Me.DTO.Products If Me.DTO.ProductsOut.Count > 0 Then Return Me.DTO.ProductsOut Return Nothing End Function End Class
Le problème c'est que l'on a pas l'intellissence (c'est facheux)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Dim UnePromoDetailDemo As PromoDetail(Of PROMO_ICT_DTO.PromoDetailDemo) = New PromoDetail(Of PROMO_ICT_DTO.PromoDetailDemo)(New PROMO_ICT_DTO.PromoDetailDemo(1, Nothing, "", "", True, 1, Nothing, "")) UnePromoDetailDemo.DTO.comment = "coucou" MessageBox.Show(UnePromoDetailDemo.DTO.Comment) Dim UnePromoDetailOwn As PromoDetail(Of PROMO_ICT_DTO.PromoDetailOwn) = New PromoDetail(Of PROMO_ICT_DTO.PromoDetailOwn)(New PROMO_ICT_DTO.PromoDetailOwn(1, Nothing, "", "", True, 1, Nothing, Nothing)) UnePromoDetailOwn.DTO.Note = "remarque" MessageBox.Show(UnePromoDetailOwn.DTO.Note)
Cela doit venir de la propriété déclarée en object, mais impossible de la déclarer de type T (je dois oublier quelque chose). Tu auras peut-être une idée.
A voir si c'est exploitable dans ton contexte de travail, je ne peux pas tout émuler.
C'est intéressant .
Je n'ai malheureusement pas le temps de tester cette approche pour le moment. C'est un peu la panique ici.
Je suis cependant étonné qu'il ne faille pas caster la propriété DTO dans la fonction GetProducts.
Es-tu bien en Option Strict On et Option Explicit On ??
Arf, quand je fais des tests j'oublie toujours cette Option Strict On. (et il ne veut pas les liaisons tardives)
Ne perds pas de temps avec cette idée.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager