Wie kann ich eine C#-Methode in eine andere Klasse auslagern und das Ergebnis zurückgeben?

2 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Es gibt 2 Möglichkeiten. Entweder du nutzt statische Methoden oder du erstellst eine Instanz einer Klasse Calculator. Um Namensverwechslungen zu vermeiden: Die Calculator-Klasse sollte die Berechnungen durchführen, eine andere Klasse (bpsw. namens CalculatorView) kann sich um die GUI kümmern.

a) Statische Methode in einer (möglicherweise statischen) Klasse:

public static class Calculator 
{
   public static decimal GetSum(decimal summand1, decimal summand2)
   {
      return summand1 + summand2;
   }
}

In einer statischen Klasse dürfen nur statische Inhalte enthalten sein. Es ist aber nicht zwingend, sie an dieser Stelle statisch zu definieren. Die Methode hingegen muss statisch und nach außen hin für deine andere Klasse zugreifbar sein. Statisch bedeutet, dass die Methode nicht objektgebunden ist. Daher wird sie über den Klassennamen aufgerufen.

Der Aufruf würde dann so in etwa aussehen:

public void ShowResult(object sender, EventArgs e)
{
  if (Operator.Text == "+")
  {
     decimal numberOne, numberTwo;

if (decimal.TryParse(NumberOne.Text, out numberOne) && decimal.TryParse(NumberTwo.Text, out numberTwo)) { Result.Text = $"{Calculator.GetSum(numberOne, numberTwo)}"; }
return; }
/* ... */

Statt Parse verwende ich hier TryParse und speichere das jeweilige Ergebnis in die zuvor jeweils deklarierte Variable. Das ist sicherer, denn deine Variante wirft eine (derzeit unbehandelte) Exception, wenn das Parsen fehlschlägt. Des Weiteren nutze ich eine String-Interpolation, um das Ergebnis zu einem String umzuwandeln. Es ist kürzer.

Da du im Anschluss in so einem Fall eh nichts mehr machst, beende ich die Methode vorzeitig. Alternativ könntest du ebenso über ein switch-Statement oder zumindest if-else if nachdenken.

b) Nutzen einer Calculator-Instanz:

In diesem Fall wird die notwendige Methode (wieder öffentlich) in deiner Klasse definiert, diesmal objektgebunden:

public class Calculator 
{
public decimal GetSum(decimal summand1, decimal summand2)
{
return summand1 + summand2;
}
}

Objektgebunden bedeutet, dass der Methode bei Aufruf praktisch zu den vorliegenden Argumenten noch das Objekt selbst mit übergeben wird:

Calculator calculator = new Calculator();
calculator.GetSum(2, 3); // passes 2, 3 AND the calculator object itself

Über das Schlüsselwort this kann in der Methode dann auf dieses Objekt zugegriffen werden. Für deinen Fall ist es derzeit nicht notwendig.

Die Anwendung:

public void ShowResult(object sender, EventArgs e)
{
   decimal numberOne, numberTwo;

if (!decimal.TryParse(NumberOne.Text, out numberOne) || !decimal.TryParse(NumberTwo.Text, out numberTwo)) { // show some error message return; }
Calculator calculator = new Calculator();
if (Operator.Text == "+") { Result.Text = $"{calculator.GetSum(numberOne, numberTwo)}"; return; }
/* ... */

Diesmal habe ich gleich noch weitere Änderungen vorgenommen. Das Parsen der Eingaben würde ich einmal, am Anfang der Methode vornehmen, beide werden sie ja eh für jede verfügbare Rechenoperation benötigt. Es gibt zwar die Fälle, dass keine Rechenoperation ausgeführt wird und das Parsen von daher unnötig war, doch erachte ich hier die Lesbarkeit und Reduktion von Code als wichtiger.

Die Rechenoperation wird wie beschrieben über eine Instanz der Calculator-Klasse ausgeführt.

Fazit:

Ich würde wohl den Aufruf über eine statische Methode bevorzugen, da das Objekt selbst innerhalb der Rechenoperationen nicht benötigt wird. Beide Lösungen sind aber möglich und legitim.

Noch eine Anmerkung zu den Konventionen: Wie du sicherlich gemerkt hast, habe ich englische Bezeichner gewählt und bestimmte Bezeichner mit einem Großbuchstaben begonnen. Zumindest letztere Konvention sollte von dir auch von Anfang an eingehalten werden.

Bezeichner starten (bezogen auf deinen Code) in folgenden Fällen mit einem Großbuchstaben:

  • bei Referenzen auf UI-Elemente deiner Form
  • bei Methodennamen

Des Weiteren generiert Visual Studio zwar gern Event-Handler mit Unterstrich im Namen, allerdings widerspricht dies der Kamelhöckerschreibweise, die ebenso für C#-Code gilt. Die Methode gleich_Click sollte von daher eher GleichClick heißen, wobei dies meines Erachtens ein ziemlich unpassender Name ist. ShowResult oder ZeigeErgebnis ist da aussagekräftiger.

Wenn es eine einzelne Funktion ist, schreib am besten eine static methode, die das ganze beschreibt.

public static int rechnen(int zahl1, int zahl2){

return zahl1+ zahl 2
}

Static bedeutet das die Funktion ohne Initialisierung eines Objektes aufgerufen werden kann