PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C# - Attribute und Verständnisfragen zu Objekten


Buzzler
2009-12-14, 14:39:31
Nachdem mein Einstieg in C# und objektoriente Programmierung bisher relativ schmerzfrei abgelaufen ist, sind bei bei mir jetzt ein paar "Praxis-Fragen" aufgetaucht, die ich durch das Lesen von Tutorials bisher noch nicht beantworten konnte.

Da ist zunächst mal die "Reichweite" von Attributen. Gelten die immer nur für das, was direkt darauf folgt - sprich Klasse, Feld usw. - und für den Rest gilt das, was ohne Attribut gelten würde? Oder gilt das so lange, bis es an anderer Stelle wieder geändert wird? Oder ist das vom Attribut abhängig?

Dann frage ich mich, was bei der Instanzierung eines Objekts wirklich Speicher belegt. Methoden belegen jawohl nicht für jedes Objekt Speicher, oder? Wenn ich jetzt aber eine Liste von Objekten auf Datenträger abgespeichert habe, dann im Code eine Methode ändere oder sogar eine Methode entferne oder hinzufüge, ist die Liste dann noch genauso benutzbar oder ist sie für das geänderte Programm dann hin? Es geht mir dabei quasi um Datenbank-Konsistenz, also was ich später noch ändern darf und was nicht, wenn ich nicht ständig bei Null anfangen will.

An anderer Stelle (ohne direkten Bezug zu C#) habe ich gelesen, dass man "größere" Funktionen/Methoden immer outline deklarieren soll. Kommentare dazu? Geht das bei C# auch und wenn ja wie?

Monger
2009-12-14, 14:58:37
Da ist zunächst mal die "Reichweite" von Attributen. Gelten die immer nur für das, was direkt darauf folgt - sprich Klasse, Feld usw. - und für den Rest gilt das, was ohne Attribut gelten würde?

Mit Attribut meinst du das, was mit eckigen Klammern vor der jeweiligen Methode steht, richtig?

Ein Attribut ist eine Art "Wrapper" für das jeweilige Element. Bevor dieses aufgerufen wird, schaut die .NET Runtime per Reflection, ob irgendwelche Attribute an der Stelle existieren, und wertet diese aus bevor die Methode/Klasse etc. betreten wird.


Dann frage ich mich, was bei der Instanzierung eines Objekts wirklich Speicher belegt.

Gute Frage. Da muss man zwischen zwei Typen unterscheiden: den Referenztypen und den Value-Typen. Wenn ein Attribut ein Referenztyp ist, steht in diesem Attribut letztendlich nichts anderes als die "Objektnummer" des jeweiligen Objekts.
Value Typen (wie z.B. Integer, Single, Double etc.) stehen dagegen unmittelbar als Wert im Speicher.

Das hat zur Folge, dass es bei Referenztypen sehr, SEHR schwierig ist, wirklich zu bestimmen wieviel Speicherplatz ein einzelnes Objekt benötigt, weil sich die einzelnen Objekte gegeneinander kaum isolieren lassen. Ein String "bla" mag drei Buchstaben à 8 Bit enthalten - aber was wenn ich zehn Strings mit dem Inhalt "bla" habe? Die teilen sich dann nämlich möglicherweise diesen Inhalt, und damit auch den Speicherverbrauch.


Wenn ich jetzt aber eine Liste von Objekten auf Datenträger abgespeichert habe, dann im Code eine Methode ändere oder sogar eine Methode entferne oder hinzufüge, ist die Liste dann noch genauso benutzbar oder ist sie für das geänderte Programm dann hin?

Das hängt von der Serialisierungsvariante ab. Die "klassische" Serialisierung, d.h. ich schau mir den Arbeitsspeicher in einem bestimmten Bereich an, und kopiere die Nullen und Einsen direkt auf Festplatte, ist heute aus genau dem Grund den du genannt hast praktisch ausgestorben. Die Robustheit von solchen Datenformaten ist verdammt schlecht.

Buzzler
2009-12-14, 15:32:57
Danke erstmal für die Antwort!

Mit Attribut meinst du das, was mit eckigen Klammern vor der jeweiligen Methode steht, richtig?
Ja. Die ganzen Bezeichnung sind mir zwar noch nicht hundertprozentig geläufig, aber ich dachte eigentlich, dass da kein Interpretationsspielraum ist. :)

Ein Attribut ist eine Art "Wrapper" für das jeweilige Element.{..}
Nochmal zur Sicherheit: Es gilt also wirklich nur einmalig, ja?

Gute Frage. Da muss man zwischen zwei Typen unterscheiden: den Referenztypen und den Value-Typen.
Soviel wusste ich zumindest schon. :) Value-Typen sind diesbezüglich ja relativ witzlos.

Das hat zur Folge, dass es bei Referenztypen sehr, SEHR schwierig ist, wirklich zu bestimmen wieviel Speicherplatz ein einzelnes Objekt benötigt, weil sich die einzelnen Objekte gegeneinander kaum isolieren lassen. Ein String "bla" mag drei Buchstaben à 8 Bit enthalten - aber was wenn ich zehn Strings mit dem Inhalt "bla" habe? Die teilen sich dann nämlich möglicherweise diesen Inhalt, und damit auch den Speicherverbrauch.
Das hängt dann aber schlicht davon ab, ob die Attribute das selbe Objekt referenzieren, korrekt?

Mir geht es eigentlich um etwas Anderes. Angenommen ich habe eine Klasse, die drei Integers (bzw. ganz allgemein Wertetypen) enthält und eine public override ToString() Methode. Hat die Methode Einfluss auf den Speicherinhalt?

Das hängt von der Serialisierungsvariante ab.
verbose, please.

Die "klassische" Serialisierung, d.h. ich schau mir den Arbeitsspeicher in einem bestimmten Bereich an, und kopiere die Nullen und Einsen direkt auf Festplatte, ist heute aus genau dem Grund den du genannt hast praktisch ausgestorben. Die Robustheit von solchen Datenformaten ist verdammt schlecht.
Mal zum Hintergrund, weshalb die Fragen bei mir überhaupt aufgetaucht sind: Es geht aktuell um eine Mod für Sims3. Da gibt es die Attribute [Persistable] bzw. [PersistableStatic], mit denen die Engine veranlasst wird, Instanzen der entsprechenden Klasse zusammen mit dem Spielstand zu speichern und beim Laden wieder zu rekonstruieren. Ich weiß also nicht und habe keinen Einfluss darauf, wie das gespeichert wird. Ich kann jetzt aber schwer davon ausgehen, dass meine persistenten Daten automatisch Schrott sind, wenn ich auch nur eine Zeile in der ToString() Methode der Klasse ändere?

Monger
2009-12-14, 15:46:26
Methoden belegen keinen Speicher. Insbesondere wenn du nur die Implementierung der ToString Methode änderst, ändert sich am Speicherabbild des Objekts rein gar nichts.

Bin allerdings unsicher, ob es da noch irgendwelche zusätzlichen Mechanismen gab. Ich weiß noch dass man bei Java eine GUID für die jeweilige Klasse vergeben hat, damit selbst bei Signatur-Änderungen das immer noch als Instanz der selben Klasse erkannt wird...
Bin aber bei .NET unsicher, was es konkret da für Mechanismen gibt.

Buzzler
2009-12-14, 16:47:45
Methoden belegen keinen Speicher. Insbesondere wenn du nur die Implementierung der ToString Methode änderst, ändert sich am Speicherabbild des Objekts rein gar nichts.
Danke, das wollte ich hören. :)

Bin allerdings unsicher, ob es da noch irgendwelche zusätzlichen Mechanismen gab. Ich weiß noch dass man bei Java eine GUID für die jeweilige Klasse vergeben hat, damit selbst bei Signatur-Änderungen das immer noch als Instanz der selben Klasse erkannt wird...
Bin aber bei .NET unsicher, was es konkret da für Mechanismen gibt.
Oha, danke für den Hinweis! So wie es aussieht, kann man bei C# bzw. .NET eine feste GUID über das entsprechende Attribut vergeben. Weiß vielleicht jemand Genaueres darüber, wie das gehandhabt wird?

Mit Signatur meinst Du jetzt die Schnittstellen-Definition?

Monger
2009-12-14, 17:21:33
Mit Signatur meinst Du jetzt die Schnittstellen-Definition?
Ja, das meine ich. Also der Deklarationsteil der Methoden und Felder.