8
votes

Est-il possible de remplacer une propriété et de renvoyer un type dérivé dans vb.net?

Considérez les classes suivantes représentant un système de commande:

Public Class WebOrder
    Inherits OrderBase        

    Public Overrides Property OrderItem as WebOrderItem 
    End Property
End Class

Public Class WebOrderItem
    Inherits OrderItemBase
End Class


3 commentaires

Définir vos articles de commande en tant que tableau est une mauvaise idée de toute façon. Utilisez une liste ou un iEnumerable.


Dans mon code réel, ils sont des listes. Désolé pour la confusion avec le ().


Voir aussi les réponses à Cette question C # pour des raisons et des astuces / Solutions de contournement. ( C # Signature de la signature "Nouveau" est "ombres" dans vb.net < / a>)


3 Réponses :


7
votes

Vous ne pouvez pas faire cela - cela change la signature définie sur la base. Pour faire ce que vous essayez de faire, vous devez utiliser des génériques:

Public Class OrderBase(Of T As IOrderItem)
    Public ReadOnly Property OrderItems As IList(Of T)
End Class


6 commentaires

Votre syntaxe était correcte, mais en allant générique, vous avez manqué une chose: vous n'avez plus besoin de remplacer la propriété - la mise en œuvre de la base sera déjà correcte. De plus, nous serons probablement en mesure d'utiliser une interface plutôt que d'une classe de base pour les ordonnances. Je le nettoyai pour toi.


Aussi - j'ai incorporé mon commentaire sur l'utilisation d'une liste plutôt que d'un tableau. Je n'aime pas ça juste revenir.


Modification de la propriété sur une nervure ultérieure - autre que cela, merci de le formater pour moi.


En fait, c'est ce que j'avais à l'origine, mais cela devient désordonné. Dans le projet réel, la classe d'ordonnance dispose d'une liste de packages et chaque paquet a une liste de commandes. Bientôt, les arguments génériques deviennent un kilomètre long en raison de la nidification des articles. Il en fait également afin que vous ne puissiez jamais retourner une base de commande générique avec la base de paquetage générique et la commande de commande. Je suppose que je ne comprends tout simplement pas pourquoi je change vraiment la signature lorsque le type de retour est une sous-classe?


Dans ce cas, pourquoi changer la signature à tout moment mon commentaire sur l'ambiguïté / l'abstraction (que j'ai oublié, add: p). Si vous souhaitez renvoyer l'abstraction commune la plus basse, la propriété devrait renvoyer une IList (de commande de commande). Laissez les génériques hors de celle-ci et la signature originale seule.


Je sais qu'il y a des façons autour de cela (y compris des génériques ou des interfaces), mais ma vraie question est de savoir pourquoi cela est-il considéré comme modifiant la signature lorsque le type de retour est une sous-classe?



4
votes

Vous ne pouvez pas modifier la signature de votre classe lors de la priorité. Vous pouvez cependant renvoyer un type dérivé:

Public Class WebOrder
    Inherits OrderBase(Of WebOrderItem)

    Public Overrides ReadOnly Property OrderItem() As WebOrderItem
        Get
            Return New WebOrderItem()
        End Get
    End Property
End Class


1 commentaires

Malheureusement, cela ne permettra pas à quelqu'un d'exercer. Tenez une liste d'objets qui représentent certaines sortes de Base de commande, appelez OrderItem et d'obtenir des objets dérivés de PerdrateDeTembase. On pourrait faire cela avec des interfaces covariantes, cependant.



4
votes

Une approche est d'avoir une méthode protégée une méthode excessive, puis d'avoir une méthode publique non-utilive qui appelle la nervure ultérieure. Chaque fois que la valeur de retour de la fonction dans la classe dérivée doit modifier, poser une substitution notoverridable de la méthode ultérieure appelle une nouvelle méthode ultérieure qui renvoie plus le type plus raffiné, ainsi que Shadow la version antérieure de la fonction publique avec celle qui utilise le Nouvelle substitution. Si vb.net a permis à une classe de remplacer et d'ombre du même membre, les choses seraient beaucoup plus propres, mais il n'ya aucun moyen de le faire.

Public Class CarFactory
  Protected Overridable Function DerivedMakeCar() as Car
    ' make a car
  End Function

  Public Function MakeCar() as Car
    Return DerivedMakeCar()
  End Function

End Class

Public Class FordFactory
  Inherits CarFactory

  Protected Overrides Function DerivedMakeCar() As Car
    Return DerivedMakeFord()
  End Function

  Protected Overridable Function DerivedMakeFord() As Ford
    ' Make a Ford
  End Function

  Public Shadows Function MakeCar() As Ford
    Return DerivedMakeFord()
  End Function

End Class


0 commentaires