96 votes

Est-il possible de remplacer une méthode non virtuelle?

Est-il possible de remplacer une méthode non virtuelle? ou quelque chose qui donne des résultats similaires (autre que la création d'une nouvelle méthode pour appeler la méthode souhaitée)?

Je voudrais remplacer une méthode de Microsoft.Xna.Framework.Graphics.GraphicsDevice en pensant aux tests unitaires.

120voto

Andrew Hare Points 159332

Non, vous ne pouvez pas remplacer une non-méthode virtuelle. La chose la plus proche que vous pouvez faire est de cacher la méthode en créant un new méthode avec le même nom, mais ce n'est pas conseillé car il casse les bons principes de conception.

Mais même en cachant la méthode ne vais pas vous donner le temps d'exécution polymorphes envoi des appels de méthode comme une véritable méthode virtuelle appel. Considérons cet exemple:

using System;

class Example
{
    static void Main()
    {
        Foo f = new Foo();
        f.M();

        Foo b = new Bar();
        b.M();
    }
}

class Foo
{
    public void M()
    {
        Console.WriteLine("Foo.M");
    }
}

class Bar : Foo
{
    public new void M()
    {
        Console.WriteLine("Bar.M");
    }
}

Dans cet exemple, les deux appels à la M méthode d'impression Foo.M. Comme vous pouvez le voir, cette approche ne permet pas d'avoir une nouvelle mise en œuvre d'une méthode pour aussi longtemps que la référence à cet objet est le bon type dérivé mais qui cache une méthode de base ne pause le polymorphisme.

Je vous recommande de ne pas masquer les méthodes de base de cette manière.

J'ai tendance à côte avec ceux qui favorisent C#par défaut de comportement que les méthodes sont non-virtuel par défaut (contrairement à Java). J'irai même plus loin et dire que les classes doivent également être scellés par défaut. L'héritage est dur à concevoir pour correctement et le fait qu'il existe une méthode qui n'est pas marqué pour être virtuel indique que l'auteur de cette méthode n'a jamais prévu pour que la méthode puisse être substituée.

Edit: "les temps d'exécution des polymorphes envoi":

Ce que je veux dire par là, c'est le comportement par défaut qui se produit au moment de l'exécution lorsque vous appelez des méthodes virtuelles. Par exemple, disons que dans mon exemple de code précédent, plutôt que de définir une non-méthode virtuelle, je n'ai en fait de définir une méthode virtuelle et une véritable méthode de remplacement ainsi.

Si je devais faire appel b.Foo dans ce cas, le CLR serait de déterminer correctement le type d'objet que l' b de points de référence pour qu' Bar et l'envoi de l'appel à M de façon appropriée.

23voto

ChrisF Points 74295

Non tu ne peux pas.

Vous pouvez uniquement remplacer une méthode virtuelle - consultez le MSDN ici :

En C #, les classes dérivées peuvent contenir des méthodes portant le même nom que les méthodes de classe de base.

  • La méthode de la classe de base doit être définie virtuelle.

6voto

slugster Points 27178

Si la classe de base n'est pas scellée, vous pouvez en hériter et écrire une nouvelle méthode masquant celle de base (utilisez le mot clé "new" dans la déclaration de la méthode). Sinon, vous ne pouvez pas le remplacer, car l'auteur n'a jamais eu l'intention de le remplacer, raison pour laquelle il n'est pas virtuel.

3voto

Rory Points 1786

Je pense que vous êtes l'obtention de la surcharge et supérieur de la confusion, la surcharge signifie que vous avez deux ou plusieurs méthodes avec le même nom, mais avec différents ensembles de paramètres tout en substituant signifie que vous avez une autre mise en œuvre d'une méthode dans une classe dérivée (de ce fait, le remplacement ou la modification du comportement dans la classe de base).

Si une méthode est virtuelle, vous pouvez la remplacer en utilisant le mot-clé override dans le derrived classe. Toutefois, les méthodes virtuelles ne peuvent masquer l'implémentation de base en utilisant le nouveau mot à la place du mot-clé override. Le non-itinéraire virtuel est inutile si l'appelant accède à la méthode via une variable typée que le type de base comme le compilateur serait d'utiliser un statique envoi à la méthode de base (ce qui signifie le code dans votre derrived classe ne serait jamais appelé).

Il n'y a jamais rien de vous empêche d'ajouter une surcharge à une classe existante, mais seulement le code qui sait au sujet de votre classe serait en mesure d'y accéder.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X