Wann/Wofür sind Statische klassen zu verwendne?
-
Hallo,
Ich hätte da mal ein Paar fragen so zu einigen sprach Teilen:
-
Static bei Klassen
Mir ist nicht ganz klar wozu ich das brauche … bzw einsetze.
Insbesondere wie es sich mit den Methoden der Klasse verhält wenn diese nicht/auch static sind, oder diese schon aber die Klasse nicht.
Ich dachte, das ist dafür gedacht, wenn ich zB nicht eine Klasse Instantiieren will, aber trotzdem die Methoden aufrufen will.
Klappt bei mir ur irgendwie nicht immer. -
Readonly vs const
Ich hab da ein paar „static readonly string“s und meine DIE schlägt mir vor diese zu „const“s zu machen.
Was ich irgendwie nachvollziehen kann. Allerdings schlägt das kompilieren dann Fehler…
Was ist den der unterschied zw. denen ?
-
-
hans234 schrieb:
Hallo,
Ich hätte da mal ein Paar fragen so zu einigen sprach Teilen:
- Static bei Klassen
Mir ist nicht ganz klar wozu ich das brauche … bzw einsetze.
static class kann nur Methoden sowie Member enthalten, die ebenfalls static sind. Wenn du also vorher schon weißt, diese Klasse darf nur statische Elemente enthalten und nicht instanziiert werden, mach die Klasse static.
Ich hab da ein paar „static readonly string“s und meine DIE schlägt mir vor diese zu „const“s zu machen.
oO Damit wäre ich vorsichtig. readonly ist idR zu bevorzugen, besonders weil die Zuweisung zu einer readonly-Variable sowohl bei der Deklaration (compile-time) als auch im Ctor (run-time) erfolgen kann. const-Variablen müssen aber direkt bei der Deklaration (compile-time) initialisiert werden.
Fun fact: Alles was const ist, ist auch automatisch static, deshalb darf man auch nicht static const int FOO = 42; schreiben, sondern es reicht ein const int FOO = 42; (Das ist auch der Grund, warum du einen Fehler kriegst)
Edit: Manchmal mache ich ein paar lokale const-Variablen innerhalb einer Methode, um lokale Enums zu faken.
- Static bei Klassen
-
Es gibt noch einen Grund der für readonly spricht: Der Compiler ersetzt Kostanten durch ihren Wert, überall wo die Konstante verwendet wird.
Das hat Konsequenzen wenn man Konstanten aus DLLs verwendet und ihren Wert irgendwann ändern muss. Es reicht nicht aus einfach eine neue Version der DLL auszuliefern. Jeder Code der die Assembly verwendet muss ebenfalls neu übersetzt werden. Bei readonlys ist das nicht der Fall.
-
µ schrieb:
Es gibt noch einen Grund der für readonly spricht: Der Compiler ersetzt Kostanten durch ihren Wert, überall wo die Konstante verwendet wird.
Wohl wahr. const am Besten nicht public in einer public Klasse.
Das hat Konsequenzen wenn man Konstanten aus DLLs verwendet und ihren Wert irgendwann ändern muss. Es reicht nicht aus einfach eine neue Version der DLL auszuliefern. Jeder Code der die Assembly verwendet muss ebenfalls neu übersetzt werden.
Aus dem Grund vermeide ich auch Default-Werte für Parameter, denn diese werden logischerweise beim Caller reingebacken und Änderungen des Defaultparameters in der DLL treten nur in Kraft, wenn der Caller auch rekompiliert wird.
-
µ schrieb:
Es gibt noch einen Grund der für readonly spricht: Der Compiler ersetzt Kostanten durch ihren Wert, überall wo die Konstante verwendet wird.
Das hat Konsequenzen wenn man Konstanten aus DLLs verwendet und ihren Wert irgendwann ändern muss. Es reicht nicht aus einfach eine neue Version der DLL auszuliefern. Jeder Code der die Assembly verwendet muss ebenfalls neu übersetzt werden. Bei readonlys ist das nicht der Fall.DAS ist die Information des Tages. Danke dir!
-
GPC schrieb:
static class kann nur Methoden sowie Member enthalten, die ebenfalls static sind. Wenn du also vorher schon weißt, diese Klasse darf nur statische Elemente enthalten und nicht instanziiert werden, mach die Klasse static.
Also erst wenn alle Member + Methoden static sind klasse auch static.
Aber wann macht das Sinn?
das wäre wohl meine Frage ...
(Ich hab zB einige bei denen ich mich frage, warum ich die instantiiere, darin ändern tu ich nichts ...)µ schrieb:
Es gibt noch einen Grund der für readonly spricht: Der Compiler ersetzt Kostanten durch ihren Wert, überall wo die Konstante verwendet wird.
Das hat Konsequenzen wenn man Konstanten aus DLLs verwendet und ihren Wert irgendwann ändern muss. Es reicht nicht aus einfach eine neue Version der DLL auszuliefern. Jeder Code der die Assembly verwendet muss ebenfalls neu übersetzt werden. Bei readonlys ist das nicht der Fall.Das verstehe ich nicht ... wieso?
Ist der wert in der DLL anders, wird er doch auch so geladen oder?
-
hans234 schrieb:
Das verstehe ich nicht ... wieso?
Ist der wert in der DLL anders, wird er doch auch so geladen oder?Eine DLL:
public class Test { public const int Const = 23; public readonly int Readonly = 42; public static readonly int StaticReadonly = 66; }
Die Anwendung:
static void Main(string[] args) { Test t = new Test(); Console.WriteLine(Test.Const); Console.WriteLine(t.Readonly); Console.WriteLine(Test.StaticReadonly); Console.ReadKey(true); }
Ausgabe:
23 42 66
Jetzt ändern wir die DLL:
public class Test { public const int Const = 123; public readonly int Readonly = 142; public static readonly int StaticReadonly = 166; }
Und kopieren sie in das Verzeichnis der Anwendung, ohne diese neu zu übersetzen. Ausgabe:
23 142 166
Was ist passiert: Der Compiler hat beim Übersetzen der Anwendung alle Zugriffe auf Test.Const durch den Wert 23 ersetzt. Wenn sich der Konstantenwert in der DLL ändert, bleibt trotzdem 23 da stehen.
Erst bei einem erneuten Übersetzen der Anwendung steht in der ersten Zeile 123.
-
hans234 schrieb:
GPC schrieb:
static class kann nur Methoden sowie Member enthalten, die ebenfalls static sind. Wenn du also vorher schon weißt, diese Klasse darf nur statische Elemente enthalten und nicht instanziiert werden, mach die Klasse static.
Also erst wenn alle Member + Methoden static sind klasse auch static.
Umgekehrt: Wenn die Klasse static ist, darf sie nur statische Elemente enthalten.
Aber wann macht das Sinn?
das wäre wohl meine Frage ...
(Ich hab zB einige bei denen ich mich frage, warum ich die instantiiere, darin ändern tu ich nichts ...)Extension methods müssen z.B. in einer static Klasse definiert werden. Da kommt man also gar nicht drum herum.
Hat man nur normale statische Methoden und instanziert die Klasse nie, dann mach sie static. Ist semantisch wertvoll
-
µ schrieb:
Was ist passiert: Der Compiler hat beim Übersetzen der Anwendung alle Zugriffe auf Test.Const durch den Wert 23 ersetzt. Wenn sich der Konstantenwert in der DLL ändert, bleibt trotzdem 23 da stehen.
Erst bei einem erneuten Übersetzen der Anwendung steht in der ersten Zeile 123.Ich glaub dir das schon,
aber ich dachte DLL (dynamic Linked Libraries) sind eben dafür da, dass sie dynamisch gelinkt werden und nicht Sachen aus ihnen in ein executable oder so raus genommen werden ... wiederspricht doch dem Sinn der Sache ....GPC schrieb:
Hat man nur normale statische Methoden und instanziert die Klasse nie, dann mach sie static. Ist semantisch wertvoll
Naja alle (member/methoden) sind nicht statisch.
--> Also erschließt sich in folge: wann mache ich members/methoden statisch
(dann darf ich auch die Klasse statisch machen ...)
-
hans234 schrieb:
GPC schrieb:
Hat man nur normale statische Methoden und instanziert die Klasse nie, dann mach sie static. Ist semantisch wertvoll
Naja alle (member/methoden) sind nicht statisch.
--> Also erschließt sich in folge: wann mache ich members/methoden statisch
(dann darf ich auch die Klasse statisch machen ...)Na ja, bei Variablen/Properties ist die Sache klar: Soll es eine Variable pro Klasse nur 1x geben und nicht einzeln für jede Instanz, dann static.
Bei Methoden ist es ein bisschen Geschmacksfrage. Gruuuuundsätzlich kann man eine Methode static machen, wenn Sie keine Instanz-Methoden/Variablen der Klasse nutzt. Allerdings sehe ich in C# von dieser Regel ab, denn auf static-Methoden kann man nur über den Typnamen zugreifen und nicht auch über einen Instanznamen, so wie in C++. Das sieht dann meistens unschön aus, wenn man einen wilden Mix aus Instanz und Typaufrufen hat.
Ich mache das nach Gefühl, wenn es static sein kann, aber nicht unbedingt muss. Like a pro:p