Laden...

Grundsätzliche Verständnisfrage zu get und get

Erstellt von LittleTester vor einem Jahr Letzter Beitrag vor einem Jahr 595 Views
L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor einem Jahr
Grundsätzliche Verständnisfrage zu get und get

Ich arbeite gerade einen C#-Kurs durch.

Der Kurs scheint von der Sache her nicht schlecht zu sein und alle wichtigen Themen zu behandeln. Der Dozent bemüht sich auch die Sache zu erklären, verliert sich aber dann, bzw. springt wild hin und her und lässt es an praxisbezogenen Beispielen missen.

Ich habe das mit dem get und set deswegen noch nicht so ganz kapiert und hoffe, dass ihr es besser erklären könnt.

Grundsätzlich auf mein Projekt übertragen in dem Systemvariablen (beispielsweise freier Festplattenspeicher oder verbaute CPU) vom System ausgelesen werden sollen: Brauche ich da jetzt get und set oder nur get? Ich will ja die Systemvariablen bekommen, also "get". Ich will die Variable dann nicht mehr verändern, weil ich ja die Information dann habe die ich brauche. Ich muss die Information aber auch in einer Variablen speichern um den Wert dann anzeigen zu können oder ggf. weiterverarbeiten zu können (beispielsweise in eine Datenbank übertragen). Also brauche ich doch auch "set"? Aber wenn man für sowas schon beides braucht, wofür braucht man dann NUR get und NUR set? Habt ihr mir da bitte praxisnahe Beispiele? Oder habe ich schon wieder überhaupt nix kapiert und für mein Beispiel reicht "get" aus?

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

6.911 Beiträge seit 2009
vor einem Jahr

Hallo Little Tester ,

bekommen, also "get". Ich will die Variable dann nicht mehr verändern, weil ich ja die Information dann habe die ich brauche.

Das passt so und das Objekt ist dann "immutable", kann also nicht mehr verändert werden.
Die Werte der Eigenschaft kann im Konstruktor gesetzt werden.


public class Person
{
    public string Name { get; set; }
    public Date Birthdate { get; }

    public Person(string name, Date birthdate)
    {
        Name = name;
        Birthdate = birthdate;
    }
}

Name hat Getter und Setter, da sich der Name z.B. durch Heirat, Namensänderung ändern kann.
Birthdate kann sich aber nicht ändern, daher nur ein "Getter".
Um die Werte zu setzen, werden diese während der Konstruktion des Objects im sog. Konstruktor gesetzt.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

2.079 Beiträge seit 2012
vor einem Jahr

[...] NUR set?

Das habe ich tatsächlich schon mal gesehen. 😁
Aber einen sinnvollen Grund dafür kenne ich nicht, also nein, konkret diesen Fall brauchst Du eigentlich nicht.
Das gibt's vermutlich nur wegen der Vollständigkeit und weil es bei der Compiler-Architektur vermutlich einfach kein Aufwand war.

Du musst get und set aus Sicht des Objektes betrachten.
Darf man von außen diesen Wert ändern (set) oder nicht (kein set)?
Prinzipiell ist readonly/immutable/kein set aus Sicht der Wartbarkeit besser, da eine Instanz nicht von "außen" kaputt gemacht werden kann.
Aber natürlich gibt es auch Fälle, wo von "außen" etwas geändert werden können muss - diese Entscheidung muss man dann bei der Arbeit treffen.

16.824 Beiträge seit 2008
vor einem Jahr

In C# gibt es zwei auf den ersten Blick ähnliche Konstrukte: Felder und Eigenschaften.

Während Felder wirklich nur stupide Daten-Speicherplätze darstellen, können Eigenschaften (eben durch get und set) auch für Logik verwendet werden, was in vielen .NET Dingen auch relevant ist (Serialisierungen, Logik, WPF-Zeugs...).
Hinter der einfachsten Eigenschaft steckt immer auch ein Feld


// Aus 
public string Name { get; set; } // Auto Property

// macht der Compiler vereinfacht dargestellt
private string _name;
public string Name
{
   get { return _name; }
   set { _name = value; }
}

Hinzu kommt, dass Eigenschaften eben Zugriffsmodifizierer hat um angeben zu können, wie und von wem ein Wert manipuliert werden kann.

Aber wenn man für sowas schon beides braucht, wofür braucht man dann NUR get und NUR set? Habt ihr mir da bitte praxisnahe Beispiele?

Das sind eben Besonderheiten, um Änderungen etc zu vermeiden - mehr oder minder also "Berechtigungen", wann der Wert manipuliert werden kann.
Eine Eigenschaft, die nur einen get hat, kann über den Konstruktor gesetzt werden; also nur bei der Initialisierung des Objekts.

Eigenschaften haben auch zusätzliche Einschränkungsmöglichkeiten wie required, init bzw. protected, private etc...
init keyword - C# Reference
required modifier - C# Reference


public float MyProperty { get; private set; } // Kann von Außen gelesen, aber nur innerhalb der Klasse gesetzt werden

Set-Only Properties (i.d.R. als Write Only) haben durchaus Anwendungsberechtigungen; eben weil Eigenschaften auch Logik auslösen können.
Bei Werten ist das tatsächlich im Gaming Bereich (also Unity) weit verbreitet, um mehrere Eigenschaftswerte zeitgleich zu setzen.


public class MyClass
{
    public float Val1{ get; set; }
    public float Val2 { get; set; }
    public float Val3 { get; set; }

    public float Val
    {
       set 
       {
           Val1 = value;
           Val2 = value;
           Val3 = value;
       }
    }
}

Aber im Endeffekt gelten Write-Only als Bad Practise, und es gibt dazu mittlerweile auch ein Warning.
CA1044: Properties should not be write only (code analysis) - .NET
Aber valide Anwendungsfälle gibt es. In Deinem Fall, wenn Du die Werte beim Erzeugen über den Konstruktor setzt, brauchst Du kein set; nur ein get.

Mit Eigenschaften in C# kann man also sehr komplexe Szenarien umsetzen, was in anderen Sprachen nur aufwändig über (mehrere) Methoden (oder gar nicht) zu machen ist.

M
368 Beiträge seit 2006
vor einem Jahr

... get und set...

Das sind Methodennamen, und wie jede Methode beinhalten sie eine Teilmenge elementarer Befehle. Wobei "get" und "set" vom Compiler gesondert behandelt werden (im Ggs. zu anderen Bezeichnungen).

 { get; set; }

ist übrigens eine valide Kurzschreibweise, wenn nur Werte gelesen oder gesetzt werden sollen.

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor einem Jahr

Ich danke euch so weit.
Ich finde das Thema sehr schwierig und habe für mich, bzw. übertragen auf mein Projekt den Nutzen noch nicht so wirklich verstanden, akzeptiere aber, dass es für die Programmierung wichtig ist. Vielleicht liege ich aber auch grundsätzlich falsch und zum Auslesen der verschiedenen Systemvariablen ist das Thema überhaupt nicht wichtig und ich versuche (krampfhaft) etwas auf mein Projekt zu übertragen, was gar keinen Sinn ergeben kann?

@Abt (und alle anderen): Du kennst ja mein Projekt Systeminventory bei dem ich versuche Systeminformationen auszulesen und anzuzeigen. Hat ja in Version 1 dank eurer Hilfe auch geklappt. Kannst du die Frage einfach nur mit "Sinnvoll" oder "Nicht sinnvoll" beantworten ob das Konzept von get und set für diese Sache sinnvoll ist oder ich mich in was verrenne? Wir reden erstmal nur vom auslesen und anzeigen. API zur Übertragung an eine Datenbank oder andere Dinge sind noch kein Thema. V2 startet bei Null auf Basis von .Net 6. Ich habe nochmal ein Screen angehängt.
(Bitte keine Codebeispiele. Wenn es sinnvoll ist will ich von alleine drauf kommen und ggf. dann lieber nochmal nachfragen, ob ich es richtig umgesetzt und damit verstanden habe.)

Ich mache den Kurs jetzt weiter und vielleicht erschließt sich mir das ganze im weiteren Verlauf auch noch. Man merkt hier wirklich, dass ein guter Kurs nicht nur einfach die Grundlagen und Techniken anhand simpler Beispiele erklärt, sondern das Ganze in einem praxisbezogenem Projekt auch angewendet werden muss. Das hat mir bei PHP extrem geholfen und quasi nach ~1,5 Jahrzehnten! zum Durchbruch verholfen, weil der Dozent eines Kurses (Aktualisierte Neuauflage hier) das gemacht hat. (Ein Projekt, das mit fortschreiten des Kurses sich verändert hat und gewachsen ist.)

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

16.824 Beiträge seit 2008
vor einem Jahr

@Abt (und alle anderen): Du kennst ja mein Projekt Systeminventory bei dem ich versuche Systeminformationen auszulesen und anzuzeigen.

Ich seh so viel Code pro Woche, wenn Du mir Montags was zeigst weiß ich Dienstagabend nicht mehr wie Dein Code aussah oder worums ging.
Ich merk mir auch nicht jedes Thema, sorry.

Hat ja in Version 1 dank eurer Hilfe auch geklappt. Kannst du die Frage einfach nur mit "Sinnvoll" oder "Nicht sinnvoll" beantworten ob das Konzept von get und set für diese Sache sinnvoll ist oder ich mich in was verrenne?

Eigenschaften machen in jedem Modell sinn, in denen Daten übertragen werden.
Es ist ein Grundmittel für die Objektorientierung und den Zugriff auf Informationen eines Objekts.

Siehe Docs für eine Kurzübersicht:
Properties - C# Programming Guide

S
40 Beiträge seit 2022
vor einem Jahr

Wenn ich mir einen Zusatz erlauben darf, was ich kürzlich gelesen hab, was ich als sehr interessant empfinde.

Quelle: https://www.uni-trier.de/universitaet/wichtige-anlaufstellen/zimk/downloads-broschueren/programmierung/c
Seite: 279

Schreibende Feldzugriffe auch in klasseneigenen Methoden durch Eigenschaftszugriffe zu ersetzen, bringt ohne Performanz-Beeinträchtigung (in der Release-Konfiguration) einige Vorteile:
 Maßnahmen zur Sicherung der Objektkonsistenz sind leichter realisierbar.
 Im Multi-Threading - Betrieb ist die Koordination von mehreren, schreibend zugreifenden Threads leichter realisierbar.
 Beim Debugging ist man nicht auf einen Datenhaltepunkt angewiesen, sondern kann einen (weniger aufwändigen) Code-Haltepunkt verwenden.
Es wird daher explizit empfohlen, schreibende Feldzugriffe auch in klasseneigenen Methoden durch Eigenschaftszugriffe zu ersetzen.1

16.824 Beiträge seit 2008
vor einem Jahr

Der einzig valide Punkt hier wäre eigentlich

Maßnahmen zur Sicherung der Objektkonsistenz sind leichter realisierbar.

Mit Threading-Mechanismen haben Eigenschaften nichts zutun, oder ändern irgendwas.

Und..

Methoden durch Eigenschaftszugriffe zu ersetzen, bringt ohne Performanz-Beeinträchtigung

Rational: wenn man nicht weiß, was Eigenschaften sind oder wie mit diesen Umgegangen wird, dann ist ein Verweis auf Performance total unangebracht. Keine Ahnung was die Uni Trier da meint schreiben zu müssen.
Das hat null Mehrwert, für Lesende hier null hilfreich (weil andere Sorgen) - und davon abgesehen auch nicht wahr.
Auch wenn das absolute Micro Optimierung ist, und daher eher ein Fall für die Profi-Ebene ist, ist der Geschwindigkeitsnachteil trotz Inlining gegenüber Feldern immens (zumindest war er das mal bei ~30%).
Die Anwendung von Eigenschaften sollte man aber nicht von diesem Fakt abhängig machen, weil es zu 100% der Alltagsanwendungen irrelevant ist; bzw. nur in super seltenen Ausnahmen relevant ist.

S
40 Beiträge seit 2022
vor einem Jahr

@Abt, danke für deine Antwort.

Warum ich das geteilt hab. Was mir als Anfänger auffällt ist, dass man die Basics zwar vermittelt bekommt von einem Kurs, aber oft solche Kleinigkeiten vergessen wird. Ich weiss es nicht. bin noch sehr weit davon entfernt mir überhaubt gedanke darüber zu machen, inwiefern solche Kleinigkeiten optimiert werden können. Hab mir aber die Frage gestellt, was ich denn nun im Code ansprechen soll. Das Feld oder die Eigenschaft und wenn es nur einen kleinen Unterschied macht, warum nicht die Eigenschaft direkt? Das wäre halt angenehm für Lerndende, wenn es ihnen so vermittelt werden würde. Hab da schon mehrere solche Fälle schon mitbekommen, wo ich aussteigen muss. Nicht passend zum aktuellen Thema, Anscheindend sind Interfaces und Poliphormie Vererbungen vorzuziehen. Ich bin froh, wenn ein Interface erstellen kann und Vererbung langsam anfange zu verstehen🙂

16.824 Beiträge seit 2008
vor einem Jahr

Danke, denn Du bestätigst genau meine Aussage, dass das totaler Humbug ist. Auch die Uni Trier kann das eigentlich besser.

Was mir als Anfänger auffällt ist, dass man die Basics zwar vermittelt bekommt von einem Kurs, aber oft solche Kleinigkeiten vergessen wird. Ich weiss es nicht. bin noch sehr weit davon entfernt mir überhaubt gedanke darüber zu machen, inwiefern solche Kleinigkeiten optimiert werden können.

Genau das ist das Problem: Du bekommst so viel Wissen als Einsteiger, dass es am Rande ist zu viel zu werden. Und dann noch auch so eine unnützliche (hier sogar falsche) Info, die Dich dann dazu verleitet Dinge falsch zu lernen.
Es geht darum solche Dinge wie Eigenschaften zu verstehen und anwenden zu können.

Es ist null hilfreich da schon von Optimierungen zu reden. Bei ~50h/Woche die letzten 10 Jahre hab ich nicht einen Fall bei mir oder Kunden gesehen, bei dem das Sinn gemacht hätte.
Im Gegenteil: ich hatte schon Kunden, bei denen "nur Felder wegen Performance" verwendet werden "durfte" (was in den Fällen gar nicht stimmte) - und die teilweise solche Verbiegungen machen mussten, dass Zeugs immens umständlich und unwartbar wurde, wegen einer Fehlannahme.
So werden hunderttausende von Euros verbrannt und richtiger Bullshit produziert.

Auch bei Deinem Thema zu static und Performance: vergiss den Quatsch. Lern erst mal die Sprache, die richtige Anwendung und die Runtime und mach Dir dann Sorgen, wenn es weh tut. So verlierst Du Zeit und Wissen. Auf Deutsch: keine Sau interessierts ob das Zeug nun 10.002 Nanosekunden dauert oder 10.003 Nanosekunden. Das ist nur für 0.0000000001% der Devs interessant.

Wenn ich behaupte, dass man das niemals in seinem Leben benötigt, dann wird das für >99.9999% der Devs zutreffen.
Daher ja: Felder sind technisch performanter, aber in fast 100% der Fällen ist diese Eigenschaft irrelevant. Daher kann man den Performance-Bezug hier einfach fallen lassen und die Aussage wird besser.

Das Feld oder die Eigenschaft und wenn es nur einen kleinen Unterschied macht, warum nicht die Eigenschaft direkt?

Weils zwei verschiedene Konzepte sind, für verschiedene Anwendungsfälle. Nochmal, wie oben: Ein Feld ist ein "dummer" Datenspeicher. Eine Eigenschaft ist ein "intelligentes" Zugriffskonzept.
Richtig angewendet ist das kein Äquivalent, sondern eine Ergänzung.

4.937 Beiträge seit 2008
vor einem Jahr

Im Multi-Threading - Betrieb ist die Koordination von mehreren, schreibend zugreifenden Threads leichter realisierbar.

Mit Threading-Mechanismen haben Eigenschaften nichts zutun, oder ändern irgendwas.

Damit ist wohl gemeint, daß man im Setter dann (an einer Codestelle) einen lock benutzen kann, anstatt bei jedem (öffentlichen) Feldzugriff explizit.

S
40 Beiträge seit 2022
vor einem Jahr

Danke Abt, genau das ist der Punkt. Ich versuche das unnütze weg zu lassen. Beispiel "var" super typ. ich verwende kein Var mehr, nur noch um schnell ausgeben zu lassen mit was ich denn nun eigentlich arbeite. oder Datetime, oder Interpolation..... Static hat mich wirklich gequält, weil ich nie wusste ob nun static oder nicht. Warum es nicht gleich richtig lernen, dann brauch ich mir, wenn ich besser werde nicht mehr darüber gedanken machen, dass es nun doch anders benutzt werden sollte.

16.824 Beiträge seit 2008
vor einem Jahr

Damit ist wohl gemeint, daß man im Setter dann (an einer Codestelle) einen lock benutzen kann, anstatt bei jedem (öffentlichen) Feldzugriff explizit.

Also Logik. Dann hätte man das auch simpel und einfach mit Logik beschreiben sollen und nicht dem Anfänger so ein Brett vor den Kopf zu schlagen 😉
Kritisiere also diesen Absatz schon sehr; auch wenn die PDF insgesamt eher zu den deutlich besseren Werken im Netz gehört.

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor einem Jahr

@Abt (und alle anderen): Du kennst ja mein Projekt Systeminventory bei dem ich versuche Systeminformationen auszulesen und anzuzeigen.
Ich seh so viel Code pro Woche, wenn Du mir Montags was zeigst weiß ich Dienstagabend nicht mehr wie Dein Code aussah oder worums ging.
Ich merk mir auch nicht jedes Thema, sorry.

OK, dachte das Thema hätte einen bleibenden Eindruck hinterlassen. 😉
Der Code sah seinerzeit so aus: (Auszug, natürlich alles in die Form1.cs geklatscht.)


// Deklaration
string computerCpu;

// Prozessor auslesen
try
{
    var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
    using (ManagementObjectCollection managementObjectCollection = searcher.Get())
    {
        ManagementObject managementObject = managementObjectCollection.OfType<ManagementObject>().FirstOrDefault();
        computerCpu = managementObject["name"].ToString();
    }
}
catch (Exception)
{
    MessageBox.Show("Problem im Abschnitt Prozessor");
}

// Ausfüllen der Label
lblComputerCpu.Text = computerCpu;

So habe ich das im Grunde mit allen Werten gemacht die ich ausgelesen habe. Am Ende hatte ich einen Schlauch von ~700-800 Zeilen Code nur um an die Informationen zu kommen und diese anzuzeigen.

Würde / Sollte man sowas mit get/set und Methoden lösen, bzw. sogar in eine Klasse auslegen (Also Klasse für alle Systemvariablen, Hardwarevariablen, Monitorvariablen, Softwareinformationen, ...)? Der Screenshot oben zeigt ja, dass ich das in entsprechende Bereiche unterteilt habe.

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

16.824 Beiträge seit 2008
vor einem Jahr

Am Ende hatte ich einen Schlauch von ~700-800 Zeilen Code nur um an die Informationen zu kommen und diese anzuzeigen.

Spricht dafür, dass Du sehr viel redundanten Code hast und die Basics in [Artikel] Drei-Schichten-Architektur nicht beachtet / nicht angewendet hast.

Würde / Sollte man sowas mit get/set und Methoden lösen, bzw. sogar in eine Klasse auslegen?

Klar, weil Dein jetziges Konstrukt eben jede [Artikel] Drei-Schichten-Architektur verletzt.
Du brauchst zwingend (Daten)Objekte zur korrekten Übertragung von Werten von Quelle zu UI.

Normalerweise würde man Dein Vorhaben auch mit Datenbindung machen; auch hier sind Objekte mit Eigenschaften zwingend erforderlich.
Du hast das bisher nicht gemacht, da Du statt Datenbindung halt dem Prinzip von "Spaghetti-Code" gefolgt bist; alles so, wie man es eigentlich nicht tun sollte.
Übersicht über die Datenbindung und Windows Forms - Windows Forms .NET

Eine Folge, weil Du "einfach" drauf losgelegt hast, ohne Grundlagen zu lernen.
Daher sehr löblich, dass Du das nun (endlich) nachholst 😉

L
LittleTester Themenstarter:in
158 Beiträge seit 2019
vor einem Jahr

Danke für die schnelle Antwort.
Damals war es mir wichtig (schnell) was zu haben mit dem ich arbeiten kann (im Sinne von ich habe die Informationen die ich brauche)

Das habe ich jetzt und nun kann ich mich daran machen das nochmal ordentlich umzusetzen. In Sachen PHP ist das bereits passiert und ich habe neben komplett neuen Code (auf Basis von MVC) auch eine echt schöne GUI zusammengebaut (Die aber noch mit Platzhalterdaten gefüllt ist).

Jetzt ist der C#-Teil dran und da ich was habe das bereits schonmal funktioniert habe ich auch die Zeit und vor allem Ruhe das so anzugehen wie es empfohlen wird. Vor allem habe ich bereits grundlegend funktionierenden Code den ich nun halt so umbauen muss, dass er am Ende immer noch funktioniert. Ich muss mir jedoch keine Gedanken darüber machen, ob ich schon beim Auslesen und ggf. Konvertieren / Formatieren der Werte einen Fehler mache und es deswegen nicht funktioniert, sondern ich weis, dass wenn es nach der Umstellung nicht funktioniert ich die Umsetzung schlicht falsch gemacht habe.

Ich weis, dass das für viele nicht nachvollziehbar ist, aber mir hilft es etwas Schritt für Schritt anzugehen. Etwas von Anfang an "professionell" und "perfekt" lösen zu wollen, damit bin ich in vielen Bereichen (nicht nur in der Programmierung) zu oft auf die Nase gefallen. Deswegen mache ich Dinge inzwischen lieber erstmal rudimentär / provisorisch, sammle Erfahrung und verbessere es dann. Es ist nicht so, dass es länger dauert, sondern es wird überhaupt nur deswegen fertig und ein gutes Ergebnis. (Ist wie beim Führerschein. Anfangs ist man froh, wenn man eine Fahrstunde übersteht ohne den Motor abzuwürgen. Später ist dann selbst das Anfahren an einer Steigung kein Problem mehr.)

IDE: Visual Studio 2022
Sofern nicht anders genannt basieren meine Projekte auf C# und .net 6

M
368 Beiträge seit 2006
vor einem Jahr

...PHP...

PHP ist eine Skriptsprache und diese sind idR weniger anspruchsvoll was z.B. Formalien oder Gebrauch der OOP darstellt. Die Idee getter- und setter-Methoden als Container oder zentrale Kontrolle einzusetzen ist aber dieselbe wie in C#: https://www.php-einfach.de/experte/objektorientierte-programmierung-oop/php-design-patterns/get-und-set-methoden/

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉