Dies ist eher eine Dokumentation als eine echte Frage. Dies scheint noch nicht auf SO angesprochen worden zu sein (es sei denn, ich habe es verpasst).
Stellen Sie sich eine generische Klasse vor, die ein statisches Element enthält:
class Foo<T> {
public static int member;
}
Gibt es eine neue Instanz des Mitglieds für jede bestimmte Klasse oder gibt es nur eine einzige Instanz für alle Klassen vom Typ Foo?
Es kann leicht durch Code wie folgt verifiziert werden:
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
Was ist das Ergebnis und wo ist dieses Verhalten dokumentiert?
T
(Foo<int>
undFoo<string>
stellen zwei verschiedene Klassen dar und haben jeweils eine Instanz, aber mehrere Intanzen vonFoo<int>
teilen sich eine einzelne Instanz vonmember
). Ein detaillierteres Beispiel finden Sie unter: stackoverflow.com/a/38369256/336648Antworten:
Ein
static
Feld wird von allen Instanzen desselben Typs gemeinsam genutzt .Foo<int>
undFoo<string>
sind zwei verschiedene Typen. Dies kann durch die folgende Codezeile bewiesen werden:Wo dies dokumentiert ist, finden Sie in Abschnitt 1.6.5 Felder der C # -Sprachenspezifikation (für C # 3):
Wie zuvor erläutert;
Foo<int>
undFoo<string>
sind nicht die gleiche Klasse; Es handelt sich um zwei verschiedene Klassen, die aus derselben generischen Klasse aufgebaut sind. Wie dies geschieht, wird in Abschnitt 4.4 des oben genannten Dokuments beschrieben:quelle
Foo<int>
undFoo<String>
sind verschiedene Typen in C #, sind sie in Java der gleiche Typ, da Java mit Generika umgeht (Typ Lösch- / Compiler-Tricks).Das Problem hierbei ist eigentlich die Tatsache, dass "generische Klassen" überhaupt keine Klassen sind.
Generische Klassendefinitionen sind nur Vorlagen für Klassen, und bis ihre Typparameter angegeben sind, sind sie nur ein Textstück (oder eine Handvoll Bytes).
Zur Laufzeit kann ein Typparameter für die Vorlage angegeben werden, um sie zum Leben zu erwecken und eine Klasse des jetzt vollständig angegebenen Typs zu erstellen. Aus diesem Grund sind statische Eigenschaften nicht vorlagenweit, und deshalb können Sie nicht zwischen
List<string>
und umwandelnList<int>
.Diese Beziehung spiegelt irgendwie die Klassen-Objekt-Beziehung wider. So wie Klassen nicht existieren *, bis Sie ein Objekt aus ihnen instanziieren, existieren generische Klassen nicht, bis Sie eine Klasse basierend auf der Vorlage erstellen.
PS Es ist durchaus möglich zu deklarieren
Daraus ergibt sich, dass die statischen Elemente nicht gemeinsam genutzt werden können, da T für verschiedene Spezialisierungen unterschiedlich ist.
quelle
Sie werden nicht geteilt. Sie sind sich nicht sicher, wo es dokumentiert ist, aber die Analysewarnung CA1000 ( Deklarieren Sie keine statischen Elemente für generische Typen ) warnt davor, da das Risiko besteht, dass der Code komplizierter wird.
quelle
Die C # -Implementierung von Generika ist näher an C ++. In beiden Sprachen
MyClass<Foo>
undMyClass<Bar>
nicht in statischen Elementen, aber in Java. In C # und C ++MyClass<Foo>
wird beim Kompilieren intern ein völlig neuer Typ erstellt, als wären Generika Makros. Normalerweise können Sie ihre generierten Namen in der Stapelverfolgung wieMyClass'1
und sehenMyClass'2
. Aus diesem Grund teilen sie keine statischen Variablen. In Java werden Generika durch eine einfachere Methode implementiert, bei der der Compiler Code unter Verwendung nicht generischer Typen generiert und überall Typumwandlungen hinzufügt. SoMyClass<Foo>
undMyClass<Bar>
erzeugen keine zwei völlig neue Klasse in Java, anstatt sie beide derselben Klasse sindMyClass
darunter und deshalb sind sie statische Variablen teilen.quelle
Sie werden nicht wirklich geteilt. Weil das Mitglied überhaupt nicht zur Instanz gehört. Ein statisches Klassenmitglied gehört zur Klasse selbst. Wenn Sie also MyClass.Number haben, ist dies für alle MyClass.Number-Objekte gleich, da es nicht einmal vom Objekt abhängt. Sie können MyClass.Number sogar ohne Objekt aufrufen oder ändern.
Da Foo <int> jedoch nicht dieselbe Klasse wie Foo <string> ist, werden diese beiden Zahlen nicht gemeinsam genutzt.
Ein Beispiel, um dies zu zeigen:
quelle
IMO, du musst es testen, aber ich denke das
wird ausgegeben,
1
weil ich denke, dass der Compilator während der Kompilierung 1 Klasse für jede generische Klasse erstellt, die Sie verwenden (in Ihrem Beispiel:Foo<int>
undFoo<string>
).Aber ich bin nicht 100% sicher =).
Bemerkung: Ich denke, es ist weder ein gutes Design noch eine gute Praxis, solche statischen Attribute zu verwenden.
quelle