C#.NET * C++ * JAVASCRIPT * PYTHON * DIVERSES
XML * XML-SCHEMA * XPATH * XSL * XSL-FO * SVG * XQUERY * XPROC * ANT



C#.NET / C#.NET Grundlagen / C#.NET Unterprogramme

C#.NET Unterprogramme

C#.NET Unterprogramme

➪ In diesem Abschnitt geht es um die sogenannte "Unterprogrammtechnik": Um Möglichkeiten, sogenannten Methoden Parameter zu übergeben, Zuweisungen zu ermöglichen, die Methoden zu überladen. Beschrieben wird auch das Delegate-Prinzip.

Auf dieser Seite:

Fügen Sie unter Projekt|Klasse hinzufügen dem Projekt eine neue Klasse hinzu.

pic/cs_neue_Klasse_hinzufuegen.png

Geben Sie der Klasse den Namen Unterprogramme_Parameter.

pic/cs_neue_Klasse_hinzufuegen_2.png

Schon ist die Klasse im Projektexplorer sichtbar:

pic/cs_neue_Klasse_hinzugefuegt.png

Ändern Sie die Klasse in public und fügen Sie einen geeigneten XML-Kommentar hinzu


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSharpSchulung
{
  /// <summary>
  /// Die Klasse demonstriert den Umgang mit Unterprogrammtechnik
  /// </summary>
  public class Unterprogramme_Parameter
  {
  }
}

Die Methode Striche() zeichnet 50mal "=" auf die Konsole. Sie dient ale Beispiel für eine Methode, die keine Parameter erhält und keinen Wert zurückgibt.


namespace CSharpSchulung
{
  /// <summary>Die Klasse demonstriert 
  /// den Umgang mit Unterprogrammtechnik
  /// </summary>
  public class Unterprogramme_Parameter
  {
    /// <summary>Beispiel für eine Methode ohne Parameter 
    /// und ohne Wertrückgabe</summary>
    public static void Striche()
    {
      for (int i = 0; i < 50; i++) Console.Write("=");
      Console.WriteLine();
    }
  }
}

Aufrufen können Sie die Methode Striche() im Main der Klasse Program.


namespace CSharpSchulung
{ 
  public class Program
  {
    /// <summary>Haupteinsprungspunkt der Anwendung</summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
      Unterprogramme_Parameter.Striche();
      Console.ReadLine();
    }    
  }
}

Das Ergebnis ist denkbar einfach:


==================================================

Erweitern Sie die Klasse Unterprogramme_Parameter um die Methode Ausgeben.


namespace CSharpSchulung
{
  /// <summary>Die Klasse demonstriert 
  /// den Umgang mit Unterprogrammtechnik
  /// </summary>
  public class Unterprogramme_Parameter
  {
    /// <summary>
    /// Beispiel für eine Methode ohne Parameter 
    /// und ohne Wertrückgabe
    /// </summary>
    public static void Striche()
    {
      for (int i = 0; i < 50; i++) Console.Write("=");
      Console.WriteLine();
    }
    /// <summary>Beispiel für eine Methode, 
    /// die einen Integerparameter erhält
    /// aber keinen Wert zurückgibt</summary>
    /// <param name="x">wird auf Console ausgegeben</param>
    public static void Ausgeben(int x)
    {
      Console.WriteLine("Integerparameter: {0}", x);
    }
  }
}

Rufen Sie nun beide Methoden im Main auf. Das System unterstützt Sie, indem es Ihnen die XML-Kommentare im jeweiligen Kontext wiedergibt.

pic/cs_Ausgeben_Parameteruebergabe.png


namespace CSharpSchulung
{ 
  public class Program
  {
    /// <summary>Haupteinsprungspunkt der Anwendung</summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
      Unterprogramme_Parameter.Striche();
      int a = 57;
      Unterprogramme_Parameter.Ausgeben(a);
      Unterprogramme_Parameter.Striche();
      Console.ReadLine();
    }    
  }
}

Der Lohn Ihrer Mühen ist eine Konsoleausgabe dieser Form:


==================================================
Integerparameter: 57
==================================================

Fügen Sie der Klasse Unterprogramme_Parameter nun die Methoden Gib76 und Quadriere hinzu.

Gib76 ist ein Beispiel für eine Methode, die keinen Parameter erhält, aber einen Integer-Wert zurückgibt beziehungsweise einer Integer-Variablen einen Wert zuweisen kann. Im Unterschied zu Striche() und Ausgeben steht hier als Rückgabetyp int, daher muss in der Gib76-Methode auch ein return erfolgen. Und der return muss zwingend vom Typ int sein.

Quadriere ist ein Beispiel für eine Methode, die einen Integer-Parameter erhält (dieser wird unter dem Namen x angesprochen) und einen Integer-Wert zurückgibt (return), also einer Integer-Variablen einen Wert zuweisen kann.


namespace CSharpSchulung
{
  /// <summary>Die Klasse demonstriert den 
  /// Umgang mit Unterprogrammtechnik</summary>
  public class Unterprogramme_Parameter
  {
    // public static void Striche() { ... }
    // public static void Ausgeben(int x)
    /// <summary>Beispiel für eine Methode, 
    /// die keinen Parameter erhält,
    /// aber einen Wert zurückgibt 
    /// (einer Variable einen Wert zuweisen kann)</summary>
    /// <returns>gibt den Integer-Wert 76 zurück</returns>
    public static int Gib76()
    {
      int x = 76;
      return x;
    }
    // Alternative:
    // public static int Gib76() => (76);
    /// <summary>Beispiel für eine Methode, 
    /// die einen Integer-Parameter erhält,
    /// und einen Integer-Wert zurückgibt</summary>
    /// <returns>Gibt den quadrierten Integerwert zurück</returns>
    public static int Quadriere(int x)
    {
      return x * x;
    } 
    // Alternative:
    // public static int Quadriere(int x) => (x * x);
  }
}

Rufen Sie nun alle Methoden im Main auf. Sie werden feststellen, dass Sie bereits beim Editieren des Quelltextes jede wünschenswerte Unterstützung vom System erhalten, wenn Sie die XML-Kommentare sauber gepflegt haben. Schauen Sie sich zudem im Objektkatalog im Namespace CSharpSchulung auch die Dokumentation der Klasse Unterprogramme_Parameter an.


namespace CSharpSchulung
{ 
  public class Program
  {
    /// <summary>Haupteinsprungspunkt der Anwendung</summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
1      Unterprogramme_Parameter.Striche();
2      int a = 57;
3      Unterprogramme_Parameter.Ausgeben(a);
4      Unterprogramme_Parameter.Striche();
5      int eee = Unterprogramme_Parameter.Gib76();
6      Unterprogramme_Parameter.Ausgeben(eee);
7      Unterprogramme_Parameter.Striche();
8      eee = Unterprogramme_Parameter.Quadriere(eee);
9      Unterprogramme_Parameter.Ausgeben(eee);
10     Unterprogramme_Parameter.Striche();
       Console.ReadLine();
    }    
  }
}

Das Ergebnis Ihrer bisherigen Anstrengungen:


==================================================
Integerparameter: 57
==================================================
Integerparameter: 76
==================================================
Integerparameter: 5776
==================================================

OK, es hat funktioniert. Versuchen Sie die einzelnen Schritte nachzuvollziehen.

Ist soweit alles klar? Falls nicht, dann machen Sie eine kurze Pause. Prüfen Sie, was nicht klar ist. Gehen Sie den nächsten Schritt erst dann, wenn Sie die bisherigen Punkte verstanden haben und diese auch beim Programmaufruf funktionieren.

Methodenüberladung

Nun erweitern Sie den bisherigen Ansatz. Sie haben die Möglichkeit, die bisher implementierten Methoden zu überladen. Das heißt: Sie können Methoden mit anderem Inhalt, aber unter demselben Namen, noch einmal schreiben. Entscheidend ist, dass die Parameterliste eine andere ist.

Fügen Sie also der Klasse Unterprogramme_Parameter getrost folgende Codezeilen hinzu:


  /// <summary>Beispiel für eine Methode, 
  /// die einen Stringparameter erhält
  /// aber keinen Wert zurückgibt</summary>
  /// <param name="x">wird auf Console ausgegeben</param>
  public static void Ausgeben(string x)
  {
   Console.WriteLine("Stringparameter: {0}", x);
  }
  /// <summary>Beispiel für eine Methode, 
  /// die einen Double-Parameter erhält
  /// aber keinen Wert zurückgibt</summary>
  /// <param name="x">wird auf Console ausgegeben</param>
  public static void Ausgeben(double x)
  {
   Console.WriteLine("Doubleparameter: {0}", x);
  }
  /// <summary>Beispiel für eine Methode, 
  /// die einen Double-Parameter erhält,
  /// und einen Double-Wert zurückgibt</summary>
  /// <returns>Gibt den quadrierten Doublewert zurück</returns>
  public static double Quadriere(double x)
  {
   return x * x;
  }

Das System verfügt mittlerweile über drei verschiedene Methoden Ausgeben mit unterschiedlichen Parametertypen. Der Rückgabetyp ist jeweils void. Zusätzlich gibt es zwei Methoden Quadriere: Der jeweilige Rückgabetyp entspricht hier dem Parametertyp.

Die Methodenüberladung wird in diversen PC-Sprachen exzessiv genutzt. Schauen Sie sich nur im Objektkatalog (STRG+Alt+J) im Namespace System die Klasse Console und deren mehrfach implementierte WriteLine-Methode an:

pic/cs_Console_WriteLine.png

Ähnliches gilt für die Convert-Klasse (ebenfalls im Namespace System):

pic/cs_Convert_toInt32.png

Die Methodenüberladung erlaubt, eine Methode mit unterschiedlichen Parametertypen aufrufen zu können, wobei jede Variante individuell programmiert ist. Das System entscheidet anhand der übergebenen Parameterliste (die leer sein, aber auch mehrere Parameter enthalten kann), welche der implementierten Methoden zur Ausführung kommt.

Nun können Sie auch die überladenen Methoden im Main aufrufen.


namespace CSharpSchulung
{
  public class Program
  {
    /// <summary>Haupteinsprungspunkt der Anwendung</summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
      Unterprogramme_Parameter.Striche();
      int a = 57;
      Unterprogramme_Parameter.Ausgeben(a);
      Unterprogramme_Parameter.Striche();
      int eee = Unterprogramme_Parameter.Gib76();
      Unterprogramme_Parameter.Ausgeben(eee);
      Unterprogramme_Parameter.Striche();
      eee = Unterprogramme_Parameter.Quadriere(eee);
      Unterprogramme_Parameter.Ausgeben(eee);
      Unterprogramme_Parameter.Striche();
      // Aufruf der überladenen Methoden:
11    Unterprogramme_Parameter.Ausgeben("Überladene Methoden");
12    double d = 12.33;
13    Unterprogramme_Parameter.Ausgeben(d);
14    d = Unterprogramme_Parameter.Quadriere(d);
15    Unterprogramme_Parameter.Ausgeben(d);
16    Unterprogramme_Parameter.Striche();
      Console.ReadLine();
    }
  }
}

Das Ergebnis des Programmaufrufs sieht so aus:


==================================================
Integerparameter: 57
==================================================
Integerparameter: 76
==================================================
Integerparameter: 5776
==================================================
Stringparameter: Überladene Methoden
Doubleparameter: 12,33
Doubleparameter: 152,0289
==================================================

Delegates

Ein Thema sind hier noch die Funktionszeiger, die später im Rahmen des Eventhandlings wichtig werden. Fügen Sie n der Klasse class Unterprogramme_Parameter (neben den bereits implementierten Methoden) noch die Zeile public delegate void abg(string s); hinzu.


namespace CSharpSchulung
{
  /// <summary>Die Klasse demonstriert 
  /// den Umgang mit Unterprogrammtechnik
  /// </summary>
  public class Unterprogramme_Parameter
  {
    /** Bereits implementiert:
    public static void Striche()
    public static void Ausgeben(int x)
    public static int Gib76()
    public static int Quadriere(int x)
    public static void Ausgeben(string x)
    public static void Ausgeben(double x)
    public static double Quadriere(double x)
    */
    /// <summary>Beispiel für einen Delegate, 
    /// der auf eine Methode verweisen kann, 
    /// die einen Stringparameter erhält,
    /// aber keinen Wert zurückgibt.</summary>
    public delegate void abg(string s);
  }
}

Hierbei handelt es sich um einen Funktions- oder Methodenzeiger, der erlaubt, auf Methoden zuzugreifen, deren Rückgabetyp void und deren Parameter vom Typ string ist.

Nutzen können Sie den Methodenzeiger beispielsweise im Main. Hier legen Sie einen Zeiger auf die Methode Unterprogramme_Parameter.Ausgeben an. Da der Zeigertyp einen Stringparameter erzwingt (delegate void abg(string s)), kann hier nur jene Methode Ausgeben aufgerufen werden, die einen entsprechenden Parametertyp erhält.


namespace CSharpSchulung
{
  public class Program
  {
    /// <summary>Haupteinsprungspunkt der Anwendung</summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
      // Die vorherige Implementierung können Sie beibehalten
      Unterprogramme_Parameter.abg fzeiger;
      fzeiger = new Unterprogramme_Parameter.abg(
                Unterprogramme_Parameter.Ausgeben);
      fzeiger("Hallo vom Funktionszeiger");
      Console.ReadLine();
    }
  }
}

Das Ergebnis des Programmaufrufs liest sich so:


Stringparameter: Hallo vom Funktionszeiger

Tipp: Sie können sich Delegates mit generischen Templates erstellen, die Ihnen die Arbeit erleichtern:


public delegate T MyDelegate<T>(T arg);

T steht hier stellvertretend für einen Datentyp, beispielsweise int oder string.


public delegate T MyDelegate<T>(T arg);
static void DelegateDemo()
{
    MyDelegate<string> d = new MyDelegate<string>(ToUpper);
    MyDelegate<int> i = new MyDelegate<int>(Verdoppele);
    Console.WriteLine(d("Moin"));
    Console.WriteLine(i(38));
}
public static string ToUpper(string s)
{
    return s.ToUpper();
}
public static int Verdoppele(int y)
{
    return y * 2;
}

Das Resultat latuet wie erwartet:


MOIN
76

wg / 4. April 2021



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.



V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/cs_Unterprogramme_Methodenueberladung_Parameter.html