Est-il possible d'appeler la version parent d'une méthode surchargée? (C# .NET)
Dans le code ci-dessous j'ai essayé dans les deux façons d'accéder à la version parent de methodTwo, mais le résultat était toujours 2. Est-il possible d'obtenir le 1 résultat d'un ChildClass instance sans la modification de ces deux classes?
class ParentClass
{
public int methodOne()
{
return methodTwo();
}
virtual public int methodTwo()
{
return 1;
}
}
class ChildClass : ParentClass
{
override public int methodTwo()
{
return 2;
}
}
class Program
{
static void Main(string[] args)
{
var a = new ChildClass();
Console.WriteLine("a.methodOne(): " + a.methodOne());
Console.WriteLine("a.methodTwo(): " + a.methodTwo());
Console.WriteLine("((ParentClass)a).methodTwo(): "
+ ((ParentClass)a).methodTwo());
Console.ReadLine();
}
}
Mise à jour ChrisW posté ceci:
De l'extérieur de la classe, je ne sais pas
un moyen facile; mais, peut-être, je n'ai pas
savoir ce qui se passe si vous essayez
réflexion: utiliser le Type.GetMethod
méthode pour trouver les MethodInfo
associés à la méthode de la
Myclass, et ensuite appeler
MethodInfo.Invoquer
Que la réponse a été supprimé. Je me demandais si ce hack pourraient travailler, juste de la curiosité.
- La réflexion astuce ne fonctionne pas, il appelle l'enfant de la méthode de trop.
- Double Possible de Comment puis-je appeler la "base de la mise en œuvre" d'un substituée méthode virtuelle?
Vous devez vous connecter pour publier un commentaire.
Au niveau IL, vous pourriez probablement un problème
call
plutôt qu'uncallvirt
, et le travail - mais si nous nous limitons à C# ;-p (modifier darn! l'exécution des arrêts de vous:VerificationException
: "l'Opération pourrait déstabiliser le moteur d'exécution."; supprimer lavirtual
et il fonctionne très bien; trop malins...)À l'intérieur de la
ChildClass
type, vous pouvez utiliserbase.methodTwo()
- cependant, ce n'est pas possible de l'extérieur. De même, vous pouvez descendre de plus d'un niveau - il n'y a pas debase.base.Foo()
soutien.Toutefois, si vous désactivez le polymorphisme à l'aide de la méthode de masquage, vous pouvez obtenir le réponse vous voulez, mais pour de mauvaises raisons:
Maintenant vous pouvez obtenir une réponse différente à partir de l'objet même selon que la variable est définie comme une
ChildClass
ou unParentClass
.new
dans ce scénario est pour faire un type de plus en plus spécialisée. Par exemple,DbCommand
a unpublic DbParameterCollection Parameters {get;}
- maisSqlCommand : DbCommand
a unpublic new SqlParameterCollection Parameters {get;}
. Les deux Api retour le même exemple (réalisé par un autreprotected abstract
bien, à savoirDbParameterCollection
- de sorte que la valeur est toujours est unSqlParameterCollection
) - mais le plus spécifique de type expose plus de manière spécifiqueÀ l'intérieur de
ChildClass.methodTwo()
, vous pouvez appelerbase.methodTwo()
.En dehors de la classe, l'appel de
((ParentClass)a).methodTwo())
sera appelChildClass.methodTwo
. C'est l'ensemble des raisons pourquoi les méthodes virtuelles existent.Comme mentionné ci-dessus, quelque chose qui est mauvais avec votre conception de classe si vous avez besoin d'appeler "de base.de base" dans le code de PRODUCTION. Mais il est tout à fait légitime d'utiliser cette technique si vous êtes le débogage ou la recherche de certains workarrounds lors de l'utilisation de bibliothèques externes vous ne pouvez pas compiler. Il est désagréable que le C# ne proposent pas cette option directement. Encore vous pouvez utiliser Kenneth Xu solution avec de l'IL du générateur et Émettent. Elle fonctionne.
De référence et un échantillon complet voir
http://kennethxu.blogspot.cz/2009/05/cnet-calling-grandparent-virtual-method.html
Merci Kenneth Xu!
Comme Marque Gravel dit, non, pas à l'extérieur. Mais voici un autre hack que j'ai utilisées.
ChildClass
peut exposermethodTwo()
de laParentClass
pour son propre usage ou pour l'usage externe. Dans votre cas:Dans mon cas, l'enfant de la classe a introduit le concept d'un de ses collègues, et j'ai besoin d'un remplacement de
methodTwo()
d'invoquer la version de base par les pairs. Par overridding il, cependant, il a caché... Ou s'agit-il? Cette technique est venu à la rescousse.Code ci-dessus avec succès remplace méthode parent encore la valeur de la méthode parent reste inchangée.
Vous pouvez les valeurs de retour de la les Deux classe Parent et Enfant de la classe à l'aide du code ci-dessous -
À ma connaissance, une fois qu'une méthode a été remplacée ensuite, vous ne pouvez pas appeler la méthode parent.
Je pense qu'il n'est pas possible à moins de faire de l'instance de la Myclass directement.
C'est la très essence de l'héritage, polymorphisme...
Je suis tombé sur ce que vous cherchez de l'aide et a terminé avec ma propre approche de l'appel ancêtre versions d'une méthode. C'est plus une façon de contourner ce qui suppose que vous pouvez modifier la classe ancêtre:
Mettre la fonctionnalité en question, l'ancêtre de la classe dans une méthode statique, avec les paramètres nécessaires. La méthode de la classe peut appeler ça de sorte qu'il n'a pas besoin de reproduire la fonctionnalité, et la classe enfant peut appeler à cette fonctionnalité, si besoin, à l'aide de la méthode statique. De cette façon, il peut être fait, même à l'intérieur d'une méthode et peut citer spécifiques de la classe qu'il veut invoquer. Aussi, il peut accéder à plus loin en arrière ancêtres que de simples parents, qui est la limitation de l'utilisation "de base".