Pourquoi les méthodes d’extension de classe statique C # ne sont-elles pas sockets en charge?

Je sais par cette question que les méthodes d’extension ne peuvent fonctionner que sur les instances de classe, pas sur la classe statique elle-même. Cela signifie que je ne peux pas étendre les classes statiques utiles comme Convert et Math .

Ce que je veux savoir, c’est pourquoi est-ce le cas? À partir du lien ci-dessus, il y a quelques suggestions sur la façon dont l’équipe C # aurait pu implémenter ce type de fonctionnalité. Y a-t-il une raison philosophique pour laquelle il n’est pas supporté?

Par exemple, voici la raison pour laquelle il n’y a pas d’extension LINQ ForEach pour IEnumerable .

L’équipe C # aurait pu implémenter ce type de fonctionnalité. Y a-t-il une raison philosophique pour laquelle il n’est pas supporté?

Il n’y a pas de raison technique et pas de raison philosophique. Cependant, comme je le souligne souvent, je n’ai pas à fournir de justification pour ne pas faire de reportage. Les fonctionnalités ne sont pas bon marché; ils sont extrêmement coûteux et ils doivent non seulement justifier leurs propres coûts, mais aussi justifier le coût d’opportunité de ne pas faire les cent autres fonctionnalités que nous aurions pu faire avec ce budget. Nous devons justifier le coût des fonctionnalités pour nos parties prenantes, mais nous ne devons pas justifier le gain de temps et d’efforts en ne mettant pas en œuvre des fonctionnalités qui ne répondent pas à nos attentes.

En particulier, la fonctionnalité proposée ne fait rien pour LINQ; Des méthodes d’extension ont été ajoutées pour que LINQ fonctionne. Tout ce qui ne fonctionnait pas avec LINQ était très difficile à intégrer à C # 3.0; Nous avions beaucoup de travail sur le calendrier et pas beaucoup de temps pour le faire. (J’ai été surpris de constater que les propriétés automatiques ont été utilisées.) Réduire une fonctionnalité inutile avant même de la concevoir a permis de gagner beaucoup de temps et d’efforts. des choses qui font fonctionner LINQ.

En résumé: la fonctionnalité proposée n’a jamais rencontré notre avantage net par rapport au coût, et nous avons toujours eu des fonctionnalités plus importantes pour consacrer notre temps et nos efforts limités.

Après avoir lu les réponses, ainsi que des questions connexes, j’ai rassemblé ma compréhension du problème ici.

Comment fonctionnent les méthodes d’extension

Tout d’abord, il est important de comprendre que les extensions ne sont que du sucre syntaxique pour les méthodes statiques.

 // Say you have an extension method that looks like this: class Extensions { public static void Extend(this SomeClass foo) {} } // Here's how you call it SomeClass myClass; myClass.Extend(); // The comstackr converts it to this: Extensions.Extend(myClass); 

La méthode ne fait pas réellement partie de la classe. C’est pourquoi vous ne pouvez pas accéder aux membres privés à partir d’une méthode d’extension. Les méthodes d’extension ne modifient que la syntaxe C # et ne violent pas le concept d’accessibilité à la POO. En fait, si vous écrivez une méthode d’extension et une méthode statique normale qui font la même chose, puis décomstackz le MSIL, elles sont exactement les mêmes .

Pourquoi les méthodes d’extension existent

Donc, s’ils n’ajoutent pas de fonctionnalités réelles, pourquoi avoir des méthodes d’extension? La réponse est LINQ:

 // LINQ makes this easy to read array.Where(i => i&1 == 0).Select(i => i*i); // Without extension methods, we would have to do it like this Enumerable.Select(Enumerable.Where(array, i => i&1 == 0), i => i*i); 

D’une certaine manière, tout ce qui concerne LINQ n’est que du sucre syntaxique, car tout ce qu’il peut faire pourrait être écrit de manière maladroite et non LINQy. De toute évidence, l’équipe C # a estimé que la lisibilité acquise par LINQ en valait la peine, mais cela soulève la question suivante: “pourquoi sont-ils arrêtés là?”

Pourquoi pas d’autres types d’extension?

Eric Lippert, un des développeurs du compilateur C #, a décrit dans un article de blog qu’une grande partie de C # 3 créait toutes les constructions nécessaires pour LINQ: , compréhensions de requête, arborescences d’expression [et] inférence de type de méthode améliorée. “ Étant donné que l’équipe C # était l’équipe la plus limitée en ressources pour l’édition 2008 de .NET, aucun autre type d’extensions qui n’était pas ssortingctement nécessaire pour LINQ n’a été inclus.

L’équipe a envisagé d’implémenter des propriétés d’extension dans C # 4 et a en fait écrit un prototype qui fonctionnait, mais il a été abandonné quand il a découvert que l’équipe de WPF ne serait pas implémentée (ce qui était l’une des motivations de cette fonctionnalité). Eric Lipper a déclaré plus tard qu’ils considéraient les méthodes d’extension pour les classes statiques, mais ne pouvaient pas justifier les avantages réels par rapport aux coûts de mise en œuvre, de test et de maintenance.

Une solution de contournement

Il est possible d’écrire une méthode d’extension qui se rapproche:

 public static TResult DoSomething(this TType @class) { // access static methods with System.Reflection return default(TResult); } // This works, but poorly typeof(Math).DoSomething(); typeof(Convert).DoSomething(); 

Mais c’est plutôt moche. Cela nécessite de la reflection, et ne peut supporter aucun type de saisie intelligente, car tout Type peut l’appeler et ce n’est probablement pas la fonctionnalité prévue.

Je crois que la réponse à votre question est because it doesn't make any sense to extend with static methods . La principale raison de l’introduction des Extension methods n’est pas l’ extending classe que vous ne possédez pas. La principale raison est que cela permettra de réduire les méthodes d’imbrication dans des exemples comme ceux-ci:

  Enumerable.Select(Enumerable.Where(arr, i => i & 1 == 0), i => i*i); // not the best thing I ever read arr.Where(i => i&1 == 0).Select(i => i*i); // wow, I see! These are squares for odd numbers 

C’est pourquoi il n’ya pas de raison d’avoir des méthodes d’ extension pour les classes statiques.

Les méthodes d’extension opèrent sur des objects, pas sur des classes. Si vous voulez une méthode d’extension pour opérer sur une classe, je suppose que vous pouvez le faire:

 public static T DoSomething(this T @class) where T:Type { // access static methods via reflection... return @class; } 

Les extensions statiques sont possibles dans F #:

 type Platform = | Win32 | X64 override this.ToSsortingng() = match FSharpValue.GetUnionFields(this, typeof) with | case, _ -> case.Name.Replace('X', 'x') type Environment with static member Platform = if System.IntPtr.Size = 8 then Platform.X64 else Platform.Win32 

Eh bien, il ne s’agit pas seulement de ne pas être mis en œuvre, mais cela entraînera une confusion quant à la place de la méthode? Les extensions statiques ont été introduites car linq est venu dans la version ultérieure et seulement pour supporter linq de manière facile à coder, les extensions statiques sont utiles.

Les extensions statiques ne sont utiles que pour rendre le code plus lisible. Il n’a aucune signification à l’exécution ou à la compilation.