none
Klasse + Funktion/Methoden RRS feed

  • Frage

  • Hallo zusammen, 

    ich bin Anfänger, versuche aber das Beste. Kann mir da bitte eine(r) erklären. 

          
     public Bars Bars { get; }
     public double AutoProfitLevel { get; set; }

    Erste Zeile, Modifikator ist auf public und Bars ist aus der Klasse "Bars". Das ist eine Funktion/Methode mit einem Rückgabewert, zwecks "get". Ist das richtig. Ansonsten mit "void". 

    Zweite Zeile, Modifikator ist auf public und "AutoProfitLevel" ist eine Funktion/Methode mit dem Ergebnis eines double. Ebenfalls mit einem Rückgabewert durch "get" und "set". Ist das richtig?

    Ist das die Abkürzung von getter und setter, beide gehören zum Accessor! Irgendwie gibt es mehrere Vorgehensweise  für get und set zu schreiben - das verwirrt mich noch. Danke im Voraus. 

    Grüsse midatra


    • Bearbeitet midatra Sonntag, 21. April 2019 09:26
    Sonntag, 21. April 2019 09:24

Antworten

  • Hi Midatra,
    eine Klasse kann 4 verschiedene Typen von Member haben:

    1. Fields - das sind klassenweit gültige "Variablen". Sie können von außen nur begrenzt genutzt werden.

    public double fi;

    2. Properties - das sind klassenweit gültige Eigenschaften. Der Unterschied zu den Fields ist, dass sie Code sowohl für das Lesen als auch das Schreiben enthalten können. Der Code ist im Getter (Lesen) und im Setter (Schreiben) enthalten.

    public double Prop { get; set; }

    Diese kurze Schreibweise ist die Schreibweise wir eine sog. autoimplemented property. Ausprogrammiert sieht das dann so aus:

    private double _prop; // backing field = Hintergrund-Puffer
    public double Prop
    {
      get
      {
        return this._prop;
      }
      set
      {
        this._prop = value;
      }
    }

    3. Methoden - diese können aufgerufen werden, um eine Codefolge abzuarbeiten. Methoden gibt es ohne Rückgabenwert:

    public void Method1()
    {
      // abzuarbeitender Code
    }

    oder auch mit Rückgabewert (Funktionen):

    public double Method2()
    {
      // abzuarbeitender Code
      return ….; // Ergebniswert am Ende der Verarbeitung des Codes in der Methode
    }

    4. Ereignisse - diese werden den Nutzern der Klasse als optionale Möglichkeit bereitgestellt, einen "Rückruf" zu organisieren. Wenn also in der Klasse an irgendeiner Stelle ein Codestück außerhalb der Klasse beim Nutzer dieser Klasse abzuarbeiten ist, dann wird das üblicherweise über eine Ereignisroutine ausgeführt.

    Die Grenzen zwischen den Membern sind fließend. So kann man beispielsweise anstelle einer Eigenschaft mit Getter und Setter auch 2 Methoden nutzen (Set-Methode, Get-Methode). In bestimmten Situationen kann aber nur mit bestimmten Typen von Membern gearbeitet werden, z.B. bei der Eigenschaftsbindung.

    public bzw. private sind zwei der möglichen Zugriffsmodifizierer, die die Sichtbarkeit eines Member festlegen, z.B. nur in der Klasse oder auch überall außerhalb, wo die Klasse bzw. ein Objekt vom Typ dieser Klasse genutzt wird.

    Vor dem Membernamen steht in C# der Typ des Member. Bei Typen, die gelesen werden können, ist das der Typ des zurückgegebenen Wertes (z.B. double).

    Deine erste Zeile: public Bars Bars { get; } deklariert eine durch den Compiler implementierte Eigenschaft mit nut einem Getter, als nur für das Lesen geeignet, ähnlich einer Konstante. Damit aber erst einmal ein Wert vorhanden ist, kann diese Eigenschaft beim Erstellen des Objektes im Konstruktor beschreiben werden. Der Konstruktor ist eine Methode in der Klasse, der einmalig beim Erzeugen eines Objektes vom Typ dieser Klasse abgearbeitet wird (new myClass() ruft public void MyClass() auf). Die Eigenschaft genau so zu benennen wie den Typ dieser Eigenschaft, ist kein guter Stil und kann später zu Mißverständnissen bei der Problembeseitigung führen. Das solltest Du ändern.

    Deine zweite Zeile ist eine öffentliche durch den Compiler implementierte Eigenschaft, die im Objekt eine lange Gleitkommazahl puffern kann (set;), die dann auch wieder ausgelesen werden kann (get;).


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Sonntag, 21. April 2019 10:00

Alle Antworten

  • Hi Midatra,
    eine Klasse kann 4 verschiedene Typen von Member haben:

    1. Fields - das sind klassenweit gültige "Variablen". Sie können von außen nur begrenzt genutzt werden.

    public double fi;

    2. Properties - das sind klassenweit gültige Eigenschaften. Der Unterschied zu den Fields ist, dass sie Code sowohl für das Lesen als auch das Schreiben enthalten können. Der Code ist im Getter (Lesen) und im Setter (Schreiben) enthalten.

    public double Prop { get; set; }

    Diese kurze Schreibweise ist die Schreibweise wir eine sog. autoimplemented property. Ausprogrammiert sieht das dann so aus:

    private double _prop; // backing field = Hintergrund-Puffer
    public double Prop
    {
      get
      {
        return this._prop;
      }
      set
      {
        this._prop = value;
      }
    }

    3. Methoden - diese können aufgerufen werden, um eine Codefolge abzuarbeiten. Methoden gibt es ohne Rückgabenwert:

    public void Method1()
    {
      // abzuarbeitender Code
    }

    oder auch mit Rückgabewert (Funktionen):

    public double Method2()
    {
      // abzuarbeitender Code
      return ….; // Ergebniswert am Ende der Verarbeitung des Codes in der Methode
    }

    4. Ereignisse - diese werden den Nutzern der Klasse als optionale Möglichkeit bereitgestellt, einen "Rückruf" zu organisieren. Wenn also in der Klasse an irgendeiner Stelle ein Codestück außerhalb der Klasse beim Nutzer dieser Klasse abzuarbeiten ist, dann wird das üblicherweise über eine Ereignisroutine ausgeführt.

    Die Grenzen zwischen den Membern sind fließend. So kann man beispielsweise anstelle einer Eigenschaft mit Getter und Setter auch 2 Methoden nutzen (Set-Methode, Get-Methode). In bestimmten Situationen kann aber nur mit bestimmten Typen von Membern gearbeitet werden, z.B. bei der Eigenschaftsbindung.

    public bzw. private sind zwei der möglichen Zugriffsmodifizierer, die die Sichtbarkeit eines Member festlegen, z.B. nur in der Klasse oder auch überall außerhalb, wo die Klasse bzw. ein Objekt vom Typ dieser Klasse genutzt wird.

    Vor dem Membernamen steht in C# der Typ des Member. Bei Typen, die gelesen werden können, ist das der Typ des zurückgegebenen Wertes (z.B. double).

    Deine erste Zeile: public Bars Bars { get; } deklariert eine durch den Compiler implementierte Eigenschaft mit nut einem Getter, als nur für das Lesen geeignet, ähnlich einer Konstante. Damit aber erst einmal ein Wert vorhanden ist, kann diese Eigenschaft beim Erstellen des Objektes im Konstruktor beschreiben werden. Der Konstruktor ist eine Methode in der Klasse, der einmalig beim Erzeugen eines Objektes vom Typ dieser Klasse abgearbeitet wird (new myClass() ruft public void MyClass() auf). Die Eigenschaft genau so zu benennen wie den Typ dieser Eigenschaft, ist kein guter Stil und kann später zu Mißverständnissen bei der Problembeseitigung führen. Das solltest Du ändern.

    Deine zweite Zeile ist eine öffentliche durch den Compiler implementierte Eigenschaft, die im Objekt eine lange Gleitkommazahl puffern kann (set;), die dann auch wieder ausgelesen werden kann (get;).


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Sonntag, 21. April 2019 10:00
  • Danke Peter für deine ausführliche Erklärungen - hat mir geholfen. 
    • Bearbeitet midatra Sonntag, 21. April 2019 14:44
    Sonntag, 21. April 2019 14:44
  • Hallo Peter, 

    kannst du mir bitte noch den Hintergrund- Puffer erklären?

    private double _prop; // backing field = Hintergrund-Puffer

    Grüße
    midatra


    Donnerstag, 25. April 2019 16:19
  • Hi,

    irgendwo müssen die Werte der Eigenschaften ja gespeichert werden. Das passiert in in der Regel in entsprechenden privaten Feldern wie im Beispiel _prop.

    Mittlerweile gibt es in C# und VB.NET kürzere Schreibweisen in C# halt so:

    public double Prop { get; set; }

    Dabei werden dann die im Hintergrund benötigten Felder automatisch verwaltet.

    Man kann sich bei Standardeigenschaften halt über die kürzere Schreibweise viel Schreibarbeit ersparen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport


    Donnerstag, 25. April 2019 16:35
    Moderator
  • Hi Midrata,
    ergänzend zu Stefan ist es sinnvoll, sich mal über die Speichernutzung eines Programmes Gedanken zu machen. 

    Eine Eigenschaft (Property) sind letztendlich 2 Methoden (Getter und Setter), die Werte empfangen und wieder zurückgeben. Diese Werte müssen aber irgendwo zwischen Schreiben (Setter) und Wiederauslesen (Getter) abgelegt (gepuffert) werden. Dafür dienen private Fields (klassenweit gültige Variablen). Mit der Erschaffung eines Objektes (Instanziierung) wird Speicherplatz im RAM (konkret im Heap) zugewiesen. Jedes Field bekommt da entsprechend seines Typs Platz, z.B. ein Integer im C#.NET bekommt 4 Byte, der sich in einem "Abstand" (Displacement) vom Beginn des zugewiesenen Speicherplatzes befindet. Mit der Instanziierung, die mit dem Schlüsselwort "new" ausgeführt wird, wird ein Zeiger (Pointer) auf den Speicherplatz des neu erzeugten Objektes übergeben. Dieser Zeiger wird in der Verweisvariablen abgelegt, die bei der Instanziierung genutzt wird:

    var Verweisvariable = new meineKlasse();

    Mit der Verweisvariablen organisiert der Compiler den  Zugriff auf das Field im erzeugten Objekt (=Speicherbereich), indem er die in der CPU unterstützte relative Adressierung ausnutzt: Adresse = Pointer + Displacement. Dort legt das Programm einen Wert ab (Setter) oder holt in von dort (Getter). Der Zugriff wird im C# mit der Punktnotation programmiert: Wert = Verweisvariable.Eigenschaft

    Etwas anders ist es beim Methodenaufruf mit Parametern (formale Parameter = Signatur) und bei lokalen Variablen innerhalb einer Methode. Deren Speicherplatz wird im Stack reserviert. Jedem formalen Parameter und auch jeder in einer Methode deklarierten Variable wird im Stack beim Methodenaufruf ein Platz zugewiesen und innerhalb der Methode wird dann über eine relative Adressierung (Stackanfang der Methode + Displacement) auf diese Speicherplätze zugegriffen. Außerdem werden im Stück noch verschiedene andere Werte abgelegt, wie z.B. die Rücksprungadresse, wo nach Beendigung der Methode im aufrufenden Programmabschnitt weiterzuarbeiten ist.


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Donnerstag, 25. April 2019 17:52
  • vielen Dank an beide, 

    Peter, TOP Feedback. 

    Grüße Midatra

    Montag, 29. April 2019 08:14