Warum sind statische Indexer in C # nicht zulässig? Ich sehe keinen Grund, warum sie nicht erlaubt sein sollten und außerdem könnten sie sehr nützlich sein.
Beispielsweise:
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];
}
}
Der obige Code würde stark von einem statischen Indexer profitieren. Es wird jedoch nicht kompiliert, da statische Indexer nicht zulässig sind. Warum ist das so?
foreach (var enum in Enum)
:)Antworten:
Die Indexer-Notation erfordert einen Verweis auf
this
. Da statische Methoden keinen Verweis auf eine bestimmte Instanz der Klasse haben, können Sie sie nicht verwendenthis
, und folglich können Sie die Indexer-Notation nicht für statische Methoden verwenden.Die Lösung für Ihr Problem besteht darin, ein Singleton-Muster wie folgt zu verwenden:
Jetzt können Sie
Utilities.ConfigurationManager["someKey"]
mit Indexer-Notation aufrufen .quelle
this
in einem Indexer ist nicht unbedingt erforderlich. Sie wurde wahrscheinlich vor anderen Schlüsselwörtern ausgewählt, da dies am sinnvollsten war. Für eine statische Implementierung kann die folgende Syntax durchaus sinnvoll sein :public object static[string value]
. Das Schlüsselwort muss nichtthis
in einem statischen Kontext verwendet werden.Ich glaube, es wurde als nicht besonders nützlich angesehen. Ich finde es auch schade - ein Beispiel, das ich eher benutze, ist Encoding, wo es sein
Encoding.GetEncoding("foo")
könnteEncoding["Foo"]
. Ich glaube nicht, dass es sehr oft auftaucht , aber abgesehen von allem anderen fühlt es sich nur ein wenig inkonsistent an, nicht verfügbar zu sein.Ich müsste das überprüfen, aber ich vermute, dass es bereits in IL (Intermediate Language) verfügbar ist.
quelle
instance
umstatic
in der IL für eine Eigenschaft und Getter - Verfahren auf eine Standardeigenschaft Ergebnisse in ILASM Beschwerensyntax error at token 'static'
; Ich kann mich nicht gut in die Angelegenheiten von IL einmischen, aber das klingt zumindest nach einem anfänglichen Nein.Als Workaround können Sie einen Instanzindexer für ein Singleton / statisches Objekt definieren (sagen wir, ConfigurationManager ist ein Singleton, anstatt eine statische Klasse zu sein):
quelle
Ich brauchte auch einen statischen Indexer zum Speichern von Attributen (also eher nett zu haben), also fand ich eine etwas umständliche Problemumgehung:
Erstellen Sie innerhalb der Klasse, für die Sie einen statischen Indexer haben möchten (hier: Element), eine gleichnamige Unterklasse + "Dict". Geben Sie eine schreibgeschützte statische Instanz dieser Unterklasse ein und fügen Sie dann den gewünschten Indexer hinzu.
Fügen Sie zuletzt die Klasse als statischen Import hinzu (daher die Unterklasse, um nur das statische Feld verfügbar zu machen).
und dann können Sie es entweder als Typ großgeschrieben oder ohne als Wörterbuch verwenden:
Aber leider, wenn man ein Objekt tatsächlich als "Wert" -Typ verwenden würde, wäre das Folgende noch kürzer (zumindest als Deklaration) und würde auch eine sofortige Typumwandlung ermöglichen:
quelle
Mit den neueren Konstrukten in C # 6 können Sie das Singleton-Muster mit einem Eigenschaftsausdruckskörper vereinfachen. Zum Beispiel habe ich die folgende Verknüpfung verwendet, die gut mit Code-Linsen funktioniert:
Es hat den zusätzlichen Vorteil, dass es für das Aktualisieren von älterem Code und das Vereinheitlichen des Zugriffs auf die Anwendungseinstellungen gefunden und ersetzt werden kann.
quelle
Das Schlüsselwort this bezieht sich auf die aktuelle Instanz der Klasse. Statische Elementfunktionen haben keinen this-Zeiger. Mit diesem Schlüsselwort kann auf Mitglieder innerhalb von Konstruktoren, Instanzmethoden und Instanzzugriffsgruppen zugegriffen werden (abgerufen von msdn ). Da dies auf eine Instanz der Klasse verweist, widerspricht es der Natur von static, da static keiner Instanz der Klasse zugeordnet ist.
Eine Problemumgehung ist die folgende, mit der Sie den Indexer für ein privates Wörterbuch verwenden können, sodass Sie nur eine neue Instanz erstellen und auf den statischen Teil zugreifen müssen.
Auf diese Weise können Sie den gesamten Zugriff auf ein Mitglied der Klasse überspringen und einfach eine Instanz davon erstellen und indizieren.
quelle
new ()
könnten für den Qualifikationsnamen eines Singletons verwendet worden sein stattdessen wie.Current
this
Schlüsselwort verwendet", und zweitens istthis
in der Syntaxpublic string this[int index]
streng genommen nicht einmal die Verwendung einesthis
Zeigers (wie er im Hauptteil der Instanzmethoden vorkommen kann). , aber nur eine andere Verwendung des Tokensthis
. Die Syntax siehtpublic static string this[int index]
vielleicht etwas eingängig aus, ist aber dennoch eindeutig.public static string class[int index]
.Der Grund dafür ist, dass es ziemlich schwer zu verstehen ist, was genau Sie mit einem statischen Indexer indizieren.
Sie sagen, dass der Code von einem statischen Indexer profitieren würde, aber würde es wirklich? Alles was es tun würde, ist dies zu ändern:
Das mögen:
was den Code in keiner Weise besser macht; Es ist nicht um viele Codezeilen kleiner, es ist dank der automatischen Vervollständigung nicht einfacher zu schreiben und es ist weniger klar, da es die Tatsache verbirgt, dass Sie etwas erhalten und festlegen, das Sie "Eigenschaft" nennen, und es den Leser tatsächlich dazu zwingt Lesen Sie die Dokumentation darüber, was genau der Indexer zurückgibt oder festlegt, da es keineswegs offensichtlich ist, dass es sich um eine Eigenschaft handelt, für die Sie indizieren, während Sie mit beiden:
Sie können es laut vorlesen und sofort verstehen, was der Code tut.
Denken Sie daran, dass wir Code schreiben möchten, der leicht (= schnell) zu verstehen ist, nicht Code, der schnell zu schreiben ist. Verwechseln Sie nicht die Geschwindigkeit, mit der Sie den Code festlegen können, mit der Geschwindigkeit, mit der Sie Projekte abschließen.
quelle