Pourquoi les indexeurs statiques sont-ils interdits en C #? Je ne vois aucune raison pour laquelle ils ne devraient pas être autorisés et ils pourraient en outre être très utiles.
Par exemple:
public static class ConfigurationManager
{
public object this[string name]
{
get => ConfigurationManager.getProperty(name);
set => ConfigurationManager.editProperty(name, value);
}
/// <summary>
/// This will write the value to the property. Will overwrite if the property is already there
/// </summary>
/// <param name="name">Name of the property</param>
/// <param name="value">Value to be wrote (calls ToString)</param>
public static void editProperty(string name, object value)
{
var ds = new DataSet();
var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
ds.ReadXml(configFile);
if (ds.Tables["config"] == null)
ds.Tables.Add("config");
var config = ds.Tables["config"];
if (config.Rows[0] == null)
config.Rows.Add(config.NewRow());
if (config.Columns[name] == null)
config.Columns.Add(name);
config.Rows[0][name] = value.ToString();
ds.WriteXml(configFile);
configFile.Close();
}
public static void addProperty(string name, object value) =>
ConfigurationManager.editProperty(name, value);
public static object getProperty(string name)
{
var ds = new DataSet();
var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
ds.ReadXml(configFile);
configFile.Close();
if (ds.Tables["config"] == null) return null;
var config = ds.Tables["config"];
if (config.Rows[0] == null) return null;
if (config.Columns[name] == null) return null;
return config.Rows[0][name];
}
}
Le code ci-dessus bénéficierait grandement d'un indexeur statique. Cependant, il ne se compilera pas car les indexeurs statiques ne sont pas autorisés. Pourquoi cela est-il ainsi?
foreach (var enum in Enum)
:)Réponses:
La notation de l'indexeur nécessite une référence à
this
. Étant donné que les méthodes statiques n'ont pas de référence à une instance particulière de la classe, vous ne pouvez pas les utiliserthis
avec elles et, par conséquent, vous ne pouvez pas utiliser la notation indexeur sur les méthodes statiques.La solution à votre problème consiste à utiliser un modèle singleton comme suit:
Vous pouvez maintenant appeler en
Utilities.ConfigurationManager["someKey"]
utilisant la notation indexeur.la source
this
dans un indexeur n'est pas nécessairement obligatoire, elle a probablement été choisie au-dessus des autres mots-clés car elle était la plus logique. Pour une implémentation statique, la syntaxe suivante peut être tout à fait viable:public object static[string value]
. Pas besoin d'utiliser le mot-cléthis
dans un contexte statique.Je pense que cela n'a pas été jugé très utile. Je pense que c'est dommage aussi - un exemple que j'ai tendance à utiliser est l'encodage, où
Encoding.GetEncoding("foo")
pourrait êtreEncoding["Foo"]
. Je ne pense pas que cela reviendrait très souvent, mais à part toute autre chose, il semble juste un peu incohérent de ne pas être disponible.Je devrais vérifier, mais je soupçonne que c'est déjà disponible en IL (Intermediate Language).
la source
instance
àstatic
dans l'IL pour une propriété et une méthode getter sur une propriété par défaut entraîne une plainte d'ilasmsyntax error at token 'static'
; Je ne suis pas doué pour me mêler des affaires de l'IL, mais cela ressemble au moins à un non initial.Pour contourner le problème, vous pouvez définir un indexeur d'instance sur un objet singleton / statique (disons que ConfigurationManager est un singleton, au lieu d'être une classe statique):
la source
J'avais également besoin (enfin, plutôt comme gentil à avoir) d'un indexeur statique pour stocker les attributs, j'ai donc trouvé une solution de contournement quelque peu délicate:
Dans la classe que vous souhaitez avoir un indexeur statique (ici: Element), créez une sous-classe du même nom + "Dict". Donnez-lui une valeur statique en lecture seule comme instance de ladite sous-classe, puis ajoutez votre indexeur souhaité.
Enfin, ajoutez la classe en tant qu'import statique (d'où la sous-classe pour exposer uniquement le champ statique).
et vous pouvez ensuite l'utiliser en majuscule comme Type ou sans comme dictionnaire:
Mais hélas, si l'on utilisait réellement un objet comme "valeur" -Type, alors le ci-dessous serait encore plus court (au moins comme déclaration), et fournirait également un typage immédiat:
la source
Avec les nouvelles constructions en C # 6, vous pouvez simplifier le modèle de singleton avec un corps d'expression de propriété. Par exemple, j'ai utilisé le raccourci suivant qui fonctionne bien avec code-lense:
Il présente l'avantage supplémentaire de pouvoir être trouvé et remplacé pour mettre à niveau un code plus ancien et unifier l'accès aux paramètres de votre application.
la source
Le mot-clé this fait référence à l'instance actuelle de la classe. Les fonctions membres statiques n'ont pas de pointeur this. Le mot clé this peut être utilisé pour accéder aux membres depuis des constructeurs, des méthodes d'instance et des accesseurs d'instance (récupéré à partir de msdn ). Puisque cela fait référence à une instance de la classe, il entre en conflit avec la nature de static, puisque static n'est pas associé à une instance de la classe.
Une solution de contournement serait la suivante qui vous permet d'utiliser l'indexeur sur un dictionnaire privé afin que vous n'ayez qu'à créer une nouvelle instance et vous accédez à la partie statique.
Cela vous permet d'ignorer tout l'accès à un membre de la classe et de simplement créer une instance de celui-ci et de l'indexer.
la source
new ()
pourraient avoir été utilisés pour le nom du qualificatif d'un singleton à la place, comme.Current
this
mot - clé", et deuxièmement,this
dans la syntaxe, cepublic string this[int index]
n'est même pas à proprement parler une utilisation d'unthis
pointeur (comme cela peut se produire dans le corps des méthodes d'instance) , mais juste une autre utilisation du jetonthis
. La syntaxepublic static string this[int index]
pourrait sembler un peu contre-intuitive, mais elle serait toujours sans ambiguïté.public static string class[int index]
.La raison en est qu'il est assez difficile de comprendre exactement ce que vous indexez avec un indexeur statique.
Vous dites que le code bénéficierait d'un indexeur statique, mais le serait-il vraiment? Tout ce qu'il ferait serait de changer cela:
Dans ceci:
ce qui n'améliore en rien le code; il n'est pas plus petit par de nombreuses lignes de code, ce n'est pas plus facile à écrire grâce à la saisie semi-automatique et c'est moins clair, car cela cache le fait que vous obtenez et définissez quelque chose que vous appelez `` Propriété '' et cela oblige en fait le lecteur à allez lire la documentation sur ce que l'indexeur renvoie ou définit exactement, car il n'est en aucun cas évident qu'il s'agit d'une propriété pour laquelle vous indexez, alors qu'avec les deux:
Vous pouvez le lire à haute voix et comprendre immédiatement ce que fait le code.
N'oubliez pas que nous voulons écrire du code facile (= rapide) à comprendre, pas du code rapide à écrire. Ne confondez pas la vitesse à laquelle vous pouvez établir le code avec la vitesse à laquelle vous terminez les projets.
la source