Überladen von Methoden

Im Laufe eines Software-Projekts sind Algorithmen zu entwerfen und in Methoden zu schachteln, welche zwar prinzipiell das gleiche tun, aber mit Werten von unterschiedlichen Datentypen oder einer verschiedenen Anzahl an Werten. Für solche Fälle bietet C# die Möglichkeit zur Überladung von Methoden.

Die meisten höheren Programmiersprachen erlauben überladene Methoden, neben C# beispielsweise auch C++ und Java.
Überladene Methoden haben zwei oder mehr Signaturen. Die Signatur ist die Kopfzeile einer Methode, welche die Zugriffsmöglichkeit, den Rückgabewert, den Methodennamen und die Parameter (Namen, Anzahl und Typ) beschreibt.
Die Überladung bezieht sich in C# (und den meisten anderen Programmiersprachen auch) jedoch ausschließlich auf die Parameteranzahl und die Datentypen der Parameter, denn nur diese sind bei einem Methodenaufruf maßgebend für eine klare Abgrenzung der verschiedenen Ausführungen einer überladenen Methode.

Die Methode sumTwoValues() (tatsächlich wird hier für gewöhnlich von nur einer Methode gesprochen, obwohl es sich strukturell um zwei Methoden handelt) ist überladen.
Werden der Methode zwei Werte des Typs Integer (int) übergeben, wird entsprechend ein Wert vom Typ Integer zurückgeliefert.
Sind die Parameter andernfalls aber Werte vom Typ double, liefert die Methode einen Wert vom Typ double zurück. Der Rückgabedatentyp und die Datentypen der Parameter entsprechen dem in der Signatur der Methode vorgegebenen Schema.

[csharp] private int sumTwoValues(int a, int b)
{
return a + b;
}

private double sumTwoValues(double a, double b)
{
return a + b;
}
[/csharp]

Da sich eine überladene Methode in ihren Ausführungen immer durch die Anzahl an Parametern oder den Datentypen der Parameter klar unterscheiden lassen muss, ist eine weitere Ausführung der Überladung der Methode sumTwoVariables() in beispielsweise folgender Form nicht möglich:

[csharp] // nicht möglich
private int sumTwoValues(double a, double b)
{
return (int)(a + b);
}
[/csharp]

Die überladene Methode pythagoras() unterscheidet zwei Signaturen, welche eine unterschiedliche Parameteranzahl haben. Die erste Ausführung der Methode pythagoras() hat gegenüber der zweiten einen dritten Parameter, welcher mit dem Schlüsselwort out als nicht initialisierter Refernezparameter vorgegeben wird.
Die zweite Ausführung von pythagoras() hat nur zwei Parameter und einen Rückgabewert. Diese Ausführung greift auf die erste Ausführung zurück und gibt das (durch die Referenz erworbene) Ergebnis zurück.

[csharp] private void pythagoras(double a, double b, out double c)
{
c = Math.Sqrt(a * a + b * b);
}

private double pythagoras(double a, double b)
{
double c;
pythagoras(a, b, out c);
return c;
}
[/csharp]

Das Überladen von Methoden kann leider nicht immer angewandt werden, wie das folgende Beispiel zeigt:

Die Methode multiplyValues() multipliziert beliebig viele Parameter des Typs double und liefert das Ergebnis ebenfalls als double zurück.
Das Schlüsselwort params sorgt für eine beliebige Anzahl (ein Parameterarray) an Wertetypen im vorgegeben Datentypen (hier: double). Das Parameterarray darf auch “leer” sein, wie der Aufruf von multiplyValues() (Rückgabewert: 1.0) beweist.
Eine Methode kann nur einen Parameterarray haben und somit auch nur einmal das Schlüsselwort params aufnehmen.
Das Schlüsselwort params ist nicht mit den Schlüsselwörtern ref und out kombinierbar, ein Parameterarray ist somit immer ein Wertetyp.

[csharp] private double multiplyValues(params double[] numbers)
{
double product = 1;

foreach (double number in numbers)
{
product *= number;
}

return product;
}
[/csharp]

Überladung (weitere Ausführung hinzufügen):
Soll nun noch eine Ausführung der Methode multiplyValues() aufgestellt werden, welche nur genau zwei Werte vom Typ double als Parameter annehmen soll, dann steht diese, wenn die Methode mit genau zwei Parametern aufgerufen wird, mit der Ausführung der Methode mit einer beliebigen Anzahl an Parametern in Konflikt.
Es bestünde in diesem Fall keine Klarheit, welche Methode aufzurufen ist.

Aus diesem Grund müssen die Methoden verschieden benannt und somit die Überladung umgangen werden. Beispielsweise könnte die zweite Ausführung als eigene Methode wie folgt aussehen:

[csharp]

private double multiplyTwoValues(double a, double c)
{
return multiplyValues(a, c);
}

[/csharp]