Comment dois-je appeler une sous-classe de la méthode sur un baseclass objet?
Je suis en utilisant une bibliothèque qui génère un tas de classes pour moi.
Ces classes héritent d'une classe de base commune, mais que la classe de base n'est pas de définir un couple de méthodes qui sont communs à tous les sous-classes.
Par exemple:
SubClassA : BaseClass{
void Add(ItemA item) {...}
ItemA CreateNewItem() {...}
}
SubClassB: BaseClass{
void Add(ItemB item) {...}
ItemB CreateNewItem() {...}
}
Malheureusement, la classe de base n'a pas ces méthodes. Ce serait génial:
BaseClass{
//these aren't actually here, I'm just showing what's missing:
abstract void Add(ItemBaseClass item); //not present!
abstract ItemBaseClass CreateNewItem(); //not present!
}
Puisqu'il y a une classe de base commune pour mon A+B objets et une classe de base commune pour l'Article objets, j'avais espéré profiter du merveilleux monde de polymorphisme.
Malheureusement, depuis les méthodes courantes ne sont pas réellement présentes dans la classe de base, je ne peux pas les appeler pratiquement. par exemple, ce serait parfait:
BaseClass Obj;
Obj = GetWorkUnit(); //could be SubClassA or SubClassB
ItemBaseClass Item = Obj.CreateNewItem(); //Compile Fail: CreateNewItem() isn't in the base class
Item.DoSomething();
Obj.Add(Item); //Compile Fail: Add(...) isn't in the base class
Évidemment l'incantation travail, mais alors j'aurais besoin de savoir quel type j'ai eu qui annulerait les avantages.
Comment puis-je "force" un appel à ces méthodes? Je ne suis pas inquiet à propos de l'obtention d'un objet qui n'implémente pas la méthode que je suis en train de l'appeler. Je peux vraiment faire ce que je veux en VB--je n'ai pas intellisense mais le compilateur est heureux et ça fonctionne:
CType(Obj, Object).Add(Item) //Note: I'm using C#--NOT VB
Contre, je n'ai aucun contrôle sur ces classes (qui, je pense, les règles des classes partielles).
Vous avez le contrôle sur la sous-classe? Si vous le faites, aller avec Lucero de la solution.
Haren: C# n'a pas l'Option Strict à tous. Ma solution fonctionne si vous n'avez aucun contrôle sur les classes, Lucero la solution est préférable si vous avez le contrôle sur les sous-classes.
OriginalL'auteur Michael Haren | 2009-04-16
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas appeler un non-virtuel méthode d'une classe dérivée sans avoir recours à la réflexion ou l'autre de sales tours. Si vous voulez le faire, il est facile alors:
Pourquoi est-réflexion sale tour ? 🙂 Il est assez commun de nos jours et u peut même faire exécuter également à code sans réflexion
Il est considéré comme l'un sale coup quand il faut utiliser le polymorphisme.
Haren: je me suis converti à VB pour vous. Le dernier paramètre sera les paramètres passés à la méthode, si vous en avez besoin.
Heh, j'ai pensé qu'il. Nous allons revenir à l'époque )
OriginalL'auteur Mehrdad Afshari
J'ai peut-être raté quelque chose, mais pourquoi ne pas faire et hériter d'une interface avec ces méthodes?
Si vous êtes dans le contrôle du processus de création de le cas, vous pouvez obtenir ce que vous voulez en héritant des classes que vous n'avez pas d'écrire et d'ajouter ensuite de l'interface (pas de code doit être écrit, le compilateur de la carte, l'interface de la non-méthodes virtuelles).
Peut-être que j'ai besoin d'être plus précis, alors... 😉
La droite. C'est ce que j'ai commencé avec, mais sans contrôle sur les classes, je ne peux pas le faire.
Peut-être que vous avez raison. Votre solution fonctionne même si vous avez le contrôle sur les sous-classes. Je ne suis pas sûr de il cependant. Le laisser ici, au moins pour aider les futurs visiteurs.
Donc j'aurais besoin d'une classe de chacune des trois classes (de la base, a, b) et ajouter dans une interface à chaque fois, par exemple MissingBaseMethods{ Add(); CreateNewItem();}; ajouter un peu de NotImplemented code pour la base, ignorer A et B, et ensuite instancier ces nouvelles classes?
OriginalL'auteur Lucero
De les déclarer comme virtuel:
http://msdn.microsoft.com/en-us/library/9fkccyh4(SV.71).aspx
Les méthodes de classe de base doivent être virtuel, avec le "remplacer" le mot-clé dans la sous-classe des implémentations. Voir ma réponse ci-dessous.
les méthodes ne sont pas dans la classe de base. J'ai commenté plus loin sur votre réponse.
OriginalL'auteur Stu
Une autre possibilité est d'utiliser un proxy mécanisme, comme un RealProxy (pas très efficace en termes de rendement) ou mieux en utilisant créé dynamiquement DynamicMethods de sorte que la surcharge de l'aide de la réflexion n'est là qu'une seule fois par type de support, tout en le gardant aussi souple que la méthode de réflexion. Cela rapporte gros quand vous devez appeler la méthode plusieurs fois, mais il nécessite une certaine MSIL connaissances.
OriginalL'auteur Lucero
Le problème n ° 1: votre sous-classes ne sont pas quelque chose de primordial
Problème n ° 2: votre sous-classes ont différentes signatures de fonction de votre classe de base
Assurez-vous que vos signatures sont correctes, et si vous êtes à leur remplaçant, marquer virtuel et non pas abstraite. Vous aurez à ajouter un vide corps de la classe de base des fonctions virtuelles, si vous n'en voulez pas à faire quoi que ce soit.
OriginalL'auteur MStodd
Si vous utilisez Visual Studio 2008 - vous pouvez créer une extension de la méthode de la classe de base. À l'intérieur de cette méthode d'extension, vous feriez la distribution et de l'appel à la sous-classe de la méthode. Cela devrait fonctionner pour la 2.0 cadre de projets ciblés ainsi, aussi longtemps que vous êtes la compilation de dans VS 2008. L'emprunt de l'autre a proposé une réflexion code, vous pouvez faire ce qui suit...
C'est une belle idée, mais le point principal est d'éliminer big switch blocs comme celui-ci. Merci, bien.
si vous ne voulez pas le commutateur blocs - aller avec la réflexion de la route. Si la performance est un sujet de préoccupation, le bloc de commutateurs peut être une meilleure voie. Avoir de la méthode d'extension vous permet de vous isoler cet interrupteur bock en une méthodes appelables.
un 2ème pensée, pourquoi ne pas faire une méthode d'extension qui n'réflexion?
En général, je ne pouvais pas le dire, mais dans ce cas, c'est parce que je ne suis pas à l'aide de VS2008. Merci encore.
OriginalL'auteur Scott Ivey
Vous avez oublié le "remplacer" le mot-clé dans votre sous-classes de définitions de méthode. Quand quelque chose est déclaré "abstrait" par définition, il est virtuel, et donc dans le sous-classe, vous devez mettre le "remplacer" le mot-clé devant la déclaration de la méthode. Que doivent faire le travail ci-dessous:
Cela devrait fonctionner exactement comme vous le souhaitez dans votre exemple d'utilisation.
Ah, je vois. Donc, fondamentalement, vous êtes à la recherche pour l'interface comme le comportement sur des choses qui ne déclarent pas d'une interface commune. Un peu de mauvaise qualité à la conception si les choses avec les méthodes courantes de ne pas implémenter une interface. Trop mauvais.
OriginalL'auteur Kevin Anderson