83 votes

Pourquoi le 'ce' mot-clé nécessaire pour appeler une méthode d'extension à partir de l'intérieur de l'étendue de la classe

J'ai créé une méthode d'extension pour un ASP.NET MVC ViewPage, e.g:

public static class ViewExtensions
{
    public static string Method<T>(this ViewPage<T> page) where T : class
    {
        return "something";
    }
}

Lors de l'appel de cette méthode à partir d'un point de Vue (dérivant de l' ViewPage- )), je reçois le message d'erreur "CS0103: Le nom de "Méthode" n'existe pas dans le contexte actuel", sauf si j'utilise l' this mot-clé de l'appeler:

<%: Method() %> <!-- gives error CS0103 -->
<%: this.Method() %> <!-- works -->

Pourquoi l' this mot-clé nécessaire? Ou faut-il travailler sans elle, mais je suis en manque de quelque chose?

(Je pense qu'il doit être un double de cette question, mais je n'ai pas pu en trouver un)

Mise à jour:

Comme Ben Robinson dit, la syntaxe pour appeler les méthodes d'extension est juste compilateur de sucre. Alors pourquoi ne pas le compilateur de vérifier automatiquement l'extension pour les méthodes de type actuel de types de base, sans nécessiter de ce mot-clé?

56voto

Eric Lippert Points 300275

Quelques points:

Tout d'abord, la proposition de la fonction (implicite"." sur une extension de l'appel de méthode) est inutile. Les méthodes d'Extension ont été nécessaires pour la requête LINQ interprétations de travailler à la manière dont nous voulions; le récepteur est toujours mentionnée dans la requête de sorte qu'il n'est pas nécessaire à l'appui implicite de ce faire LINQ travail.

Deuxièmement, la fonction travaille contre la plus générale, la conception de méthodes d'extension: à savoir, que les méthodes d'extension vous permettent d'étendre un type que vous ne pouvez pas vous étendre, soit parce que c'est une interface et que vous ne connaissez pas la mise en œuvre, ou parce que vous savez de la mise en œuvre, mais n'ont pas le code source.

Si vous êtes dans le cas où vous êtes en utilisant une méthode d'extension d'un type à l'intérieur de ce type , alors vous ne avez accès au code source. Pourquoi utilisez-vous une méthode d'extension en premier lieu, puis? Vous pouvez écrire une méthode d'instance vous-même si vous avez accès au code source de l'extension de type, et puis vous n'avez pas à utiliser une méthode d'extension à tous! Votre application peut alors profiter d'un accès à la privé de l'état de l'objet, les méthodes d'extension ne peuvent pas.

Ce qui facilite l'utilisation des méthodes d'extension à partir de l'intérieur d'un type que vous avez accès à l'est d'encourager l'utilisation de méthodes d'extension sur les méthodes d'instance. Les méthodes d'Extension sont grands, mais il est généralement préférable d'utiliser une méthode d'instance si vous en avez un.

Compte tenu de ces deux points, la charge ne tombe plus sur la langue designer pour expliquer pourquoi la fonction n'a pas d' exister. Il incombe maintenant de vous expliquer pourquoi il devrait. Les caractéristiques ont d'énormes coûts qui y sont associés. Cette fonctionnalité n'est pas nécessaire et fonctionne à contre-indiqué les objectifs de la conception de méthodes d'extension; pourquoi devrions-nous prendre sur le coût de la mise en œuvre? Expliquer ce que convaincante, scénario important est activée par cette fonctionnalité et nous allons envisager la mise en œuvre dans le futur. Je ne vois pas du tout convaincante, scénario important qui justifie cela, mais peut-être il y en a un que j'ai manqué.

9voto

Ferruccio Points 51508

Sans elle, le compilateur voit juste comme une méthode statique dans une classe statique qui prend en page comme c'est le premier paramètre. c'est à dire

// without 'this'
string s = ViewExtensions.Method(page);

vs

// with 'this'
string s = page.Method();

6voto

Alex Humphrey Points 2794

Sur les méthodes d'instance, " il " est implicitement passé à chaque méthode de manière transparente, de sorte que vous pouvez accéder à tous les membres de l'offre.

Les méthodes d'Extension sont statiques. En appelant Method() plutôt que d' this.Method() ou Method(this), vous n'êtes pas raconter le compilateur de ce qu'à passer à la méthode.

Vous pourriez dire: "pourquoi n'est-il pas juste de réaliser ce que l'objet appelant et le passer en paramètre?'

La réponse est que les méthodes d'extension sont statiques et peuvent être appelées à partir d'un contexte statique, où il n'y a pas de "il".

Je suppose qu'ils pourraient vérifier que lors de la compilation, mais pour être honnête, il est sans doute beaucoup de travail pour très peu de gain. Et pour être honnête, je ne vois guère d'intérêt à ôter de la précision de la méthode d'extension des appels. Le fait qu'ils peuvent être confondus avec des méthodes d'instance signifie qu'ils peuvent être assez peu intuitive à la fois (à l'exception nullreferenceexceptions pas être jeté par exemple). Parfois, je pense qu'ils devraient avoir introduit un nouveau pipe-en avant le style de l'opérateur pour les méthodes d'extension.

4voto

stakx Points 29832

Il est important de noter qu' il existe des différences entre les méthodes de vulgarisation et des méthodes régulières. Je pense que vous venez de croiser l'un d'entre eux.

Je vais vous donner un exemple d'une autre différence: Il est assez facile de faire appel à une méthode d'extension sur un null référence d'objet. Heureusement, c'est beaucoup plus difficile de le faire avec des méthodes régulières. (Mais il peut être fait. IIRC, Jon Skeet montré comment faire en manipulant code CIL.)

static void ExtensionMethod(this object obj) { ... }

object nullObj = null;
nullObj.ExtensionMethod();  // will succeed without a NullReferenceException!

Cela étant dit, je suis d'accord qu'il semble un peu unlogical qu' this est nécessaire d'appeler la méthode d'extension. Après tout, une méthode d'extension devrait, idéalement, "sentir" et de se comporter comme un normal.

Mais en réalité, les méthodes d'extension sont plus comme du sucre syntaxique ajouté sur le dessus de la langue qu'un début de fonctionnalités de base qui s'intègre bien dans la langue, à tous les égards.

1voto

Ben Robinson Points 14558

Parce que la méthode d'extension n'existe pas avec la classe ViewPage. Vous devez indiquer au compilateur ce que vous appelez la méthode d'extension. Rappelez-vous this.Method() est juste compilateur de sucre pour ViewExtensions.Method(this). Il est de la même manière que vous ne pouvez pas appeler une extension de la méthode au sein du milieu de toute la classe par le nom de la méthode.

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