'Ombres' vs. 'Remplace' dans VB.NET
Quelle est la signification des deux mots-clés Les ombres et Remplace? Ce qu'ils font et dans quel contexte est l'un ou l'autre préférable?
- Vous pourriez envisager d'accepter @Nick réponse, car il est beaucoup plus utile. (D'ailleurs, c'est un peu déroutant d'avoir une grisé réponse sur le dessus...)
- Je ne le pense pas. La accepté de répondre, explique ce qu'ils font et pourquoi l'occultation n'est pas exactement préférable.
Vous devez vous connecter pour publier un commentaire.
Je ne considère pas les Ombres à être vraiment un concept de la programmation orientée objet. Remplace indique que vous êtes en offrant de nouvelles ou des fonctionnalités supplémentaires pour une méthode/etc propriété qui a été déclarée dans une classe ancêtre. Les ombres vraiment des trucs le compilateur en pensant que la méthode parent/etc propriété n'existe même pas.
Je l'ai pas utiliser pour les Ombres. Stick à des Remplacements. Ces types de peu de "caractéristiques" que VB est fourni pour les années finissent toujours par vous causer du chagrin à un certain point.
Remplace est le plus normal de la qualification. Si l'enfant de la classe redéfinit une classe de base de la fonction de cette façon, alors peu importe la façon dont un enfant de l'objet référencé (à l'aide d'une classe de base, ou un enfant de la classe de référence), il est l'enfant de la fonction qui est appelée.
D'autre part, si l'enfant de fonction de classe Ombres la classe de base de la fonction, puis un objet enfant accessible via une base de référence de classe utilisera la classe de base de la fonction, en dépit d'être un enfant de l'objet.
L'enfant définition de fonction n'est utilisée que si l'enfant objet est accessible à l'aide d'un correspondant de référence de l'enfant.
Ombrage n'a probablement pas ce que vous pensez que cela fonctionne.
Considérer les classes suivantes:
Maintenant je les utilise:
Vous pensez probablement que oA et oB sont le même droit?
Nope.
oA.fx = 0 en oB.fx = 1
À mon humble avis, c'est très dangereux de comportement et c'est à peine mentionné dans les docs.
Si vous aviez utilisé remplacer, elles doivent être la même.
Donc bien qu'il existe des utilisations légitimes pour les ombres, les chances sont que vous êtes en train de faire n'est pas l'un d'eux et il devrait être évité.
Remplace - d'Étendre ou de créer d'autres fonctionnalités pour une méthode.
Exemple: Ajouter ou de l'extension des fonctions de l'événement de Peinture d'une fenêtre.
Ombres - Redéfinit une méthode héritée et les forces de son utilisation pour toutes les classes instanciées avec ce type. En d'autres termes, la méthode n'est pas surchargé, mais redéfini et les méthodes de classe de base ne sont pas disponibles, forçant ainsi l'utilisation de la fonction déclarée dans la classe. Les ombres conserve ou conserve la définition de la méthode telle qu'elle n'est pas détruite si les méthodes de classe de base sont modifiés.
Exemple: la Force de tous les "B" des classes à utiliser, il est excentrique Ajouter la définition de telle sorte que si Une classe d'Ajouter des méthodes sont modifiés, il n'affecte pas le B de l'ajouter. (Masque l'ensemble de la classe de base "Ajouter" des méthodes. Ne sera pas en mesure d'appeler A. Add(x, y, z) à partir d'une instance de B.)
Dim x As A = new B() : x.Add(1, 2)
.Parfois un petit exemple permet de comprendre la différence dans un moyen technique.
Les "ombres" mot-clé essentiellement dit: "Si celui qui est en train d'accéder à cet objet, il sait être de ce type ou de l'un de ses descendants, l'utilisation de ce membre; sinon, utilisez la base de l'un." L'exemple le plus simple de ce qui pourrait être une classe de base ThingFactory, qui comprend une "MakeNew" méthode qui renvoie une Chose, et une classe CarFactory, dérivé de ThingFactory, dont "MakeNew" méthode retourne toujours une Chose qui sera de type dérivé de Voiture. Si une routine sait qu'une ThingFactory il détient arrive, plus particulièrement, être un CarFactory, alors il utilisera une ombre CarFactory.MakeNew (s'il en existe), qui permet de déterminer le type de retour à la Voiture. Si une routine ne sait pas que son ThingFactory est en fait un CarFactory, il va utiliser un non-ombre MakeNew (qui doit appeler un interne protégé substituables MakeDerivedThing méthode).
D'ailleurs, une autre bonne utilisation des ombres est de prévenir les classes dérivées à partir de l'accès Protégé à des méthodes qui ne fonctionnent plus. Il n'y a aucun moyen de cacher un membre de classes dérivées autre que l'attribution d'un nouveau, mais on peut prévenir les classes dérivées de faire quoi que ce soit avec un membre protégé par la déclaration d'une nouvelle protégée de classe vide avec ce nom. Par exemple, si vous appelez MemberwiseClone sur un objet serait de le casser, on peut déclarer:
Noter que cela ne viole pas les principes de la programmation orientée objet, comme le Principe de Substitution de Liskov, depuis, ne s'applique que dans les cas où une classe dérivée peut être utilisé à la place d'une classe de base de l'objet. Si Foo et Bar hérite de Boz, une méthode qui accepte un Boz paramètre peut légitimement être passé dans un Foo Bar ou à la place. D'autre part, un objet de type Foo sais que sa classe de base de l'objet est de type Boz. Il ne sera jamais rien d'autre (par exemple, c'est la garantie de ne pas être un Bar).
Un exemple de l'observation: supposons que vous souhaitez utiliser une fonction dans un composant tiers, mais la fonction est protégée. Vous pouvez contourner cette contrainte avec l'héritage simple et exposant une ombre fonction qui, en gros, appelle sa fonction de base:
Je pense qu'il y a vraiment deux scénarios que les gens sont ici, et les deux sont légitimes. On pourrait diviser la classe de base designer et le développeur ans plus tard, qui est la mise en œuvre de la sous-classe qui ne peut pas modifier la classe de base. Donc oui, la meilleure chose à faire est de les remplacer, si vous avez de luxe. C'est le propre des CRUES approche.
Sur l'autre main, vous peut avoir quelque chose comme l'exemple donné ci-dessus où vous êtes à l'autre bout de cette équation avoir à mettre en œuvre une sous-classe et vous ne pouvez pas changer le fait que la méthode que vous avez besoin de remplacer n'est pas marqué substituables. Prenez l'exemple de la
Dans ce cas, je suis d'hériter de ma classe de contrôle Winform classe qui, malheureusement, n'est pas marquée comme substituables. À ce point, je suis confronté à simplement faire le code "pure" ou le rendre plus facile à comprendre. Le client de ce contrôle veut simplement le contrôle d'appel.Focus() et n'a probablement pas de soins. Je pourrais avoir nommé cette méthode FocusSearchText() ou Focus2, etc, mais je crois que ce qui précède est beaucoup plus simple pour le code client. Il est vrai que si le client jette alors ce contrôle comme la classe de base et les appels de Concentrer mon code ne excute. Mais qui est assez éloignée.
En fin de compte, il revient à un jugement d'appel, et celui que vous aurez à faire.
C'est une récente MSDN lien:
Les différences entre les zones d'ombre et primordial
Ombrage protège contre une ultérieure de la classe de base modification qui introduit un membre que vous avez déjà défini dans votre classe dérivée.
Vous utilisez normalement observation dans les cas suivants:
** Vous prévoyez que votre classe de base peut être modifié pour définir un élément en utilisant le même nom que le vôtre.*
** Vous voulez avoir la liberté de changer le type d'élément ou de la séquence d'appel.*
(Je suis encore à enquêter sur l'utilisation à l'égard de l'ampleur et les types)
Ombre vous permet de faire certaines choses qui ne peuvent pas être fait avec les remplacements.
Dans mon cas personnel: j'ai plusieurs tables classes avec les fonctionnalités génériques; mais dont le collections sont de types différents.
Puis j'ai spécifiques isntances:
Je ne pouvais pas ignorer parce que le type est modifié.
MyBase.Contents
méthodes pour "se débarrasser de" la surcharge de travail que vous ne pouvez pas utiliser.J'ai trouvé une autre différence. Voir ceci:
Si vous utilisez des Remplacements (où il est de $$$) IL n'y a AUCUN MOYEN d'utiliser la touche Func sur la classe de Base, soit si la définition de l'instance est Dérivé, et si la définition est la base, mais l'exemple est du type Dérivé.
Si vous utilisez des Ombres, la seule façon vous pouvez voir la touche Func dans la classe dérivée, est de définir l'instance en tant que Dérivé, et sans passer pour une méthode de classe de base (X. Test renvoie la Norme). Je pense que c'est le principal: Si j'utilise les Ombres, la méthode de ne pas surcharger la méthode de base à l'intérieur de la base de méthodes.
C'est de la programmation orientée objet approche de Surcharges. Si je tire une classe et EN AUCUN CAS je veux qu'une méthode doit être appelée, je dois utiliser les Surcharges. Pour les instances de mes objets, il n'y a aucun moyen de retour "Standard" (à l'Exception de l'utilisation des reflets, je pense). Je pense que intellisense faire un peu de confusion. Si je souligne Y. Func, il sera mis en surbrillance la touche Func dans la classe de base, mais est exécutée la touche Func dans la classe dérivée.
Avec les Ombres, la nouvelle méthode est uniquement accessible directement. En tant que telles que les Surcharges, mais en cachant les surcharges de la classe de base (je pense que c'est une erreur retourné avant la compilation, parce que vous pouvez appeler à l'aide d'un plâtre, comme implicite fait à l'aide d'une surcharge).
Et bien voici la réponse par le Code.
Vous pouvez copier coller et essayer vous-même. Comme vous pouvez le voir, l'observation est le comportement par défaut, et Visual Studio ne vous avertir lorsque l'observation est d'aller sur sans vous écrivant explicitement l'ombre modificateur.
Remarque: Pour moi, je n'ai jamais utilisé une classe de Base de référence à un objet enfant. Pour de tels cas, j'ai toujours utiliser des Interfaces.
Je suis d'accord avec Jim. Je n'ai jamais trouvé une utilisation légitime pour les Ombres, soit. Habituellement, si je le vois, je suppose que la sous-section du code doit être remaniée un peu.
Je suppose qu'elle est là pour que vous puissiez l'ombre d'une méthode à partir d'un assemblage dans lequel vous n'avez pas de contrôle sur le code source. Dans ce cas, le refactoring, la classe parent serait impossible.
Je voulais utiliser
System.Web.HttpContext.Current.Response
au lieu deResponse.redirect
, et ont besoin de la commodité de codeResponse.redirect
. J'ai défini une propriété readonly nomméResponse
à l'ombre de l'original dans une classe de base. Je ne pouvais pas utiliser les remplacements, car cette propriété n'est pas remplaçable. Très pratique:)Ombres peut être très utile si vous écrivez un wrapper autour d'un contrôle existant.
Par exemple autour d'une zone de liste déroulante. Par l'observation de la
AutoCompleteSource
, vous pouvez l'empêcher d'être ensemble pour un illégitime de la valeur pour votre type spécial de la zone de liste déroulante, même quand il est en fonte normale à la zone de liste déroulante. Ou pour faire de la pré-proccessing avant d'utilisermybase.AutoCompleteSource = value
dans l'occultation de la propriété.L'utilisation de l'Ombre est rare, mais vrai. En outre, vous ne pouvez pas remplacer un partagées méthode (statique). Donc, vous devez l'ombre d'une méthode partagée si vous voulez "override" il.