Pourquoi C # n'a-t-il pas de variables statiques locales comme C? Cela me manque!!
Parce qu'ils ont tout gâché et laissé de côté une fonction utile à leur convenance.
Tous les arguments sur la manière dont vous devriez coder, et sur ce qui est intelligent, et vous devriez reconsidérer votre mode de vie, sont des excuses pompeuses défensives.
Bien sûr, C # est pur et orienté vers quoi que ce soit. C'est pourquoi ils génèrent automatiquement des sections locales persistantes pour les fonctions lambda. C'est tellement compliqué. Je me sens si bête.
La portée de boucle statique est utile et importante dans de nombreux cas.
La réponse brève et réelle est que vous devez déplacer les statiques locales dans la portée de la classe et vivre avec la pollution de l’espace de nommage de la classe en C #. Prenez votre plainte à la mairie.
State fait généralement partie d'un object ou d'une partie de type et ne fait pas partie d'une méthode. (L'exception étant des variables capturées, bien sûr.)
Si vous voulez l'équivalent d'une variable statique locale, créez une variable d'instance ou une variable statique - et déterminez si la méthode elle-même doit réellement faire partie d'un type différent avec cet état.
L'entrée de blog MSDN Pourquoi C # ne prend-il pas en charge les variables de méthode statiques? traite de la question exacte posée dans le message d'origine:
Il y a deux raisons pour lesquelles C # n'a pas cette fonctionnalité.
Tout d'abord, il est possible d'obtenir presque le même effet en ayant un statique au niveau de la classe, et l’ajout de la statique de méthode nécessiterait une augmentation de complexité.
Deuxièmement, la statique au niveau de la méthode est quelque peu notoire pour avoir causé des problèmes lorsque le code est appelé à plusieurs reprises ou à partir de plusieurs threads, et comme les définitions sont dans les méthodes, il est plus difficile de trouver le définitions.
[Auteur: Eric Gunnerson]
Je ne connais pas aussi bien le C que le C #, mais je pense que vous pouvez accomplir tout ce que vous pouvez avec un statique local, en utilisant un statique de niveau classe qui n'est utilisé que par une méthode. Évidemment, cela implique certains changements syntaxiques, mais je pense que vous pouvez obtenir toutes les fonctionnalités dont vous avez besoin.
De plus, Eric Lippert répond souvent aux questions de ce type sur son blog . La réponse est généralement de cette manière : "On me demande" Pourquoi C # n'implémente-t-il pas toujours la fonctionnalité X? ". La réponse est toujours la même: car personne n'a jamais conçu, spécifié, implémenté, testé, documenté et expédié cette fonctionnalité. " Essentiellement, ses réponses se résument généralement à ajouter de la fonctionnalité, ce qui coûte de l'argent. Par conséquent, de nombreuses fonctionnalités potentielles ne sont pas implémentées, car elles ne sont pas apparues du côté positif de l'analyse coûts-avantages.
C # est un langage orienté composant et n'a pas le concept de variables en dehors du cadre d'une classe ou d'une méthode locale. Les variables d'une méthode ne peuvent pas non plus être déclarées statiques, comme vous le savez peut-être en C. Cependant, vous pouvez toujours utiliser une variable statique de classe comme substitut.
En règle générale, il existe généralement des solutions pour résoudre les problèmes de programmation en C # sans recourir à la statique au niveau de la méthode. L'état doit généralement être conçu en classes et en types, et non en méthodes.
Logiquement, oui. Ce serait la même chose qu'un membre statique de niveau classe utilisé uniquement dans cette méthode. Cependant, un membre statique au niveau de la méthode serait plus encapsulé. Si les données stockées dans un membre sont uniquement destinées à être utilisées par une seule méthode, elles ne devraient être accessibles que par cette seule méthode.
Cependant, vous POUVEZ obtenir presque exactement le même effet en C # en créant une classe imbriquée.
Vous pouvez utiliser la classe imbriquée comme solution de contournement pour cela. C # limitant la portée des variables statiques aux classes, vous pouvez utiliser nested-class en tant que portée.
Par exemple:
public class Foo {
public int Increment() {
return IncrementInternal.Increment();
}
private static class IncrementInternal {
private static int counter = 0;
public static int Increment() {
return counter++;
}
}
}
Ici Foo
prend en charge la méthode Increment
, mais sa prise en charge est assurée par la classe privée imbriquée IncrementInternal
qui contient la variable statique en tant que membre. Et bien sûr, counter
n'est pas visible dans le contexte (autres méthodes) de Foo
.
En passant, si vous souhaitez accéder au contexte Foo
(autres membres et méthodes) dans IncrementInternal.Increment
, vous pouvez passer this
en tant que paramètre à IncrementInternal.Increment
lorsque vous l'appelez à partir de Foo
.
Pour garder la portée aussi petite que possible, je suggère de créer une classe imbriquée pour chacune de ces méthodes. Et comme ce n'est probablement pas si courant, le nombre de classes imbriquées restera suffisamment petit pour le maintenir.
Je pense que c'est plus propre que les fonctions anonymes ou IIFE.
Vous pouvez voir une démo en direct ici .
Parce que les variables locales statiques sont liées à la méthode et que la méthode est partagée par toutes les instances.
J'ai dû corriger moi-même et les autres programmeurs qui s'attendent à ce qu'il soit unique par instance de classe utilisant la méthode.
Cependant, si vous en faites une classe statique ou une instance statique d'une classe, il est clairement syntaxique s'il existe une instance par classe de conteneur ou une instance du tout.
Si vous ne les utilisez pas, il devient également plus facile de refactoriser ultérieurement.
Je ne vois pas beaucoup d'avantages supplémentaires aux statistiques locales, si vous gardez vos classes simples et petites, il n'y a que peu de problème avec la pollution statique globale, ce que les défaitistes aiment se plaindre. Mais voici une autre alternative.
using System;
using System.Collections;
public class Program
{
delegate bool DoWork();
public static void Main()
{
DoWork work = Foo().GetEnumerator().MoveNext;
work();
work();
work();
}
public static IEnumerable Foo()
{
int static_x = 10;
/*
do some other static stuff....
*/
main:
//repetative housework
Console.WriteLine(static_x);
static_x++;
yield return true;
goto main;
}
}
Je pense que l’idée de la statique locale est tout aussi facile à résoudre en créant des champs statiques publics pour la classe. Très peu de changement logique, vous ne pensez pas?
Si vous pensez que ce serait un grand changement logique, j'aimerais savoir comment.
class MyClass
{
public static float MaxDepthInches = 3;
private void PickNose()
{
if (CurrentFingerDepth < MyClass.MaxDepthInches)
{
CurrentFingerDepth++;
}
}
}