Benutzer mit den meisten Antworten
Rückgabe von 2 Werten in einer Klasse

Frage
-
Hallo zusammen,
Vielleicht kurz zu meiner Person:
Ich heiße Thorsten, 30 Jahre alt und bin Entwicklungs-Ing (Maschinenbau) und schreibe in meiner Freizeit gerne mit C# kleinere Berechnungsprogramme.
Ich programmiere schon seid längerem mit der frei zugänglichen Version von C# (Express Edition) und habe bisher bevorzugt in der Windows Forms Basis die Programme gestaltet.Jetzt habe ich mir ein "Neues Projekt" zurechtgelegt und bin (leider) an meine Wissensgrenze von C# gestoßen. Vielleicht kann mir jemand von euch bei dieser (für mich) kniffligen Aufgabe helfen.
Hier der Code-Ausschnitt:
class Result { public double funktion1(double T, double xl) { //Differentiale 'dx/dTwa' und 'dh/dTwa' double diff1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); double diff2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); } }
Ich möchte nun jeweils Diff1 als auch Diff2 wieder zurück geben. Natürlich funktioniert das hier nicht, weil die funktion1 nur einen Rückgabewert haben kann. Ich weiß das ich das ganze mit get und set irgendwie erstellen kann, allerdings bin ich hier noch nicht dahinter gestiegen. Dazu kommt noch, dass diff2 von diff1 und umgekehrt abhängig ist.
Ich hoffe auf einen Ansatz von euch. Mir gehen so langsam die Ideen aus :(
Vielen Dank im Voraus.
Viele Grüße
Thorsten
Antworten
-
Hallo Thorsten,
Du kannst nicht zwei Werte auf einmal zurückgeben. Das würde mit ref bzw. out Übergabeparametern gehen, sinnvoller wäre es aber, eine Klasse mit den Rückgabewerten als Eigenschaften zu erstellen und dann eine Instanz dieser Klasse als Rückgabewert zu erstellen.
class Result { //public double funktion1(double T, double xl) // Fehlerhaft, hatte vergessen, den Rückgabewert anzupassen public Ergebnis funktion1(double T, double xl) { Ergebnis ergebnis = new Ergebnis(); //Differentiale 'dx/dTwa' und 'dh/dTwa' ergebnis.Wert1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); ergebnis.Wert2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); return ergebnis; } } public class Ergebnis { public double Wert1 { get; set; } public double Wert2 { get; set; } ... }
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Samstag, 21. Juni 2014 21:03
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 22. Juni 2014 15:23
- Als Antwort markiert Thorsten84 Sonntag, 22. Juni 2014 18:16
-
Hallo,
grundsätzlich hast du 3 Möglichkeiten:- out-Parameter verwenden. Deine Methode sieht dan ungefähr so aus:
public double funktion1(double T, double xl,out double diff1, out double diff2) { //Differentiale 'dx/dTwa' und 'dh/dTwa' diff1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); diff2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); }
Der Aufruf erfolgt dann so:
double diff1,diff2; funktion1(0,1,out diff1,out diff2); //diff1 und diff2 haben nun die in der Funktion zugewiesenen Werte
Die out-Parameter müssen vor der Übergabe nicht initialisiert werden, da diese nicht zur Parameterübergebe dienen (dafür wären normale- und ref-Parameter gedacht). out- und ref-Parameter können beide einen Wert "zurück geben".
- Eine Struktur mit den Werten zurück geben:
struct MyData{ public double Diff1{get;set;} public double Diff2{get;set;} } public MyDatafunktion1(double T, double xl) { //Differentiale 'dx/dTwa' und 'dh/dTwa' double diff1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); double diff2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); return new MyData(){Diff1=diff1,Diff2=diff2};//Neue Struktur zurück geben }
Dabei kannst du nun vom Rückgabewert die Diff1 und Diff2-Eigenschaft abfragen. - 2 Methoden verwenden. Da Diff2 nicht von Diff1 abhängig ist, musst du auch nichts doppelt berechnen o.ä.:
public double funktion1Diff1(double T, double xl) { return 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); } public double funktion1Diff2(double T, double xl) { return 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); }
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Thorsten84 Sonntag, 22. Juni 2014 18:16
- out-Parameter verwenden. Deine Methode sieht dan ungefähr so aus:
-
Hi Thorsten,
die Funktion muss an der Stelle Ergebnis zurück liefern und nicht double.
class Result { public Ergebnis funktion1(double T, double xl) { Ergebnis ergebnis = new Ergebnis(); //Differentiale 'dx/dTwa' und 'dh/dTwa' ergebnis.Wert1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); ergebnis.Wert2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); return ergebnis; } } public class Ergebnis { public double Wert1 { get; set; } public double Wert2 { get; set; } ... }
MFG
Björn
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 22. Juni 2014 15:23
- Als Antwort markiert Thorsten84 Sonntag, 22. Juni 2014 18:16
-
Hallo,
ich habe Thorsten so verstanden, das er wärend der Berechnung einige Zwischenergebnisse erhält und diese gerne mit "aufbewahren" möchte.Die läuft eigentlich ganz ähnlich zu Björns Code, nur das du eine List<double> o.ä. verwenden solltest.
class Result{ public List<double> IntermediateResults{get;set;} public Result(){ this.IntermediateResults=new List<double>();//Neue Liste initialisieren } public double Result1{get;set;} //...usw. class Calculator{ public Result funktion1(double a,double b){ Result r = new Result(); //Berechne deine Werte und füge die Zwischenergebnisse hinzu: r.IntermediateResults.Add(12.345); r.Result1 = a+b;//Die Endergebnisse return r; } }
In dem zurück gegebenen Wert kannst du dann die Liste mit den Zwischenergebnissen (IntermediateResults) wieder abfragen und weiter verarbeiten. Die Ergebnisse bleiben solange erhalten, wie du die Rückgabe der Funktion in einer Variable aufhebst.
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Thorsten84 Sonntag, 29. Juni 2014 14:50
Alle Antworten
-
Hallo Thorsten,
Du kannst nicht zwei Werte auf einmal zurückgeben. Das würde mit ref bzw. out Übergabeparametern gehen, sinnvoller wäre es aber, eine Klasse mit den Rückgabewerten als Eigenschaften zu erstellen und dann eine Instanz dieser Klasse als Rückgabewert zu erstellen.
class Result { //public double funktion1(double T, double xl) // Fehlerhaft, hatte vergessen, den Rückgabewert anzupassen public Ergebnis funktion1(double T, double xl) { Ergebnis ergebnis = new Ergebnis(); //Differentiale 'dx/dTwa' und 'dh/dTwa' ergebnis.Wert1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); ergebnis.Wert2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); return ergebnis; } } public class Ergebnis { public double Wert1 { get; set; } public double Wert2 { get; set; } ... }
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Samstag, 21. Juni 2014 21:03
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 22. Juni 2014 15:23
- Als Antwort markiert Thorsten84 Sonntag, 22. Juni 2014 18:16
-
Hallo,
grundsätzlich hast du 3 Möglichkeiten:- out-Parameter verwenden. Deine Methode sieht dan ungefähr so aus:
public double funktion1(double T, double xl,out double diff1, out double diff2) { //Differentiale 'dx/dTwa' und 'dh/dTwa' diff1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); diff2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); }
Der Aufruf erfolgt dann so:
double diff1,diff2; funktion1(0,1,out diff1,out diff2); //diff1 und diff2 haben nun die in der Funktion zugewiesenen Werte
Die out-Parameter müssen vor der Übergabe nicht initialisiert werden, da diese nicht zur Parameterübergebe dienen (dafür wären normale- und ref-Parameter gedacht). out- und ref-Parameter können beide einen Wert "zurück geben".
- Eine Struktur mit den Werten zurück geben:
struct MyData{ public double Diff1{get;set;} public double Diff2{get;set;} } public MyDatafunktion1(double T, double xl) { //Differentiale 'dx/dTwa' und 'dh/dTwa' double diff1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); double diff2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); return new MyData(){Diff1=diff1,Diff2=diff2};//Neue Struktur zurück geben }
Dabei kannst du nun vom Rückgabewert die Diff1 und Diff2-Eigenschaft abfragen. - 2 Methoden verwenden. Da Diff2 nicht von Diff1 abhängig ist, musst du auch nichts doppelt berechnen o.ä.:
public double funktion1Diff1(double T, double xl) { return 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); } public double funktion1Diff2(double T, double xl) { return 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); }
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Thorsten84 Sonntag, 22. Juni 2014 18:16
- out-Parameter verwenden. Deine Methode sieht dan ungefähr so aus:
-
Ergänzend sei hier noch Tuple<double, double> erwähnt
Mein Favorit ist in solch einem Fall ganz klar die bereits erwähnte eigene Klasse oder Struktur, die beide Werte enthält.
.
Andreas Richter
Softwareentwickler und -architekt
http://www.anrichter.net -
Hallo Stefan,
vielen Dank erstmal für deine schnelle Hilfe.
Genau so hab ich mir das vorgestellt. Danke...
Allerdings sagt er mir jetzt, das in diesem Fall eine implizite Konvertierung von "(Projekt Name).Ergebnis" in double nicht möglich ist ?!
Hab ich etwas falsch gemacht ?
-
Hi Thorsten,
die Funktion muss an der Stelle Ergebnis zurück liefern und nicht double.
class Result { public Ergebnis funktion1(double T, double xl) { Ergebnis ergebnis = new Ergebnis(); //Differentiale 'dx/dTwa' und 'dh/dTwa' ergebnis.Wert1 = 4.186 * Lambda * ((xwa - xl) / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); ergebnis.Wert2 = 4.186 * Lambda * ((xwa - xl) * 4.186 * T / ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) + ((Epsilon - 1) * ((((1.006 + 1.861 * xwa) * T + (xwa * 2500)) - ((1.006 + 1.861 * xl) * T + (xl * 2500))) - ((xwa - xl) * (2500 + 1.861 * T)))) - ((xwa - xl) * 4.186 * T))); return ergebnis; } } public class Ergebnis { public double Wert1 { get; set; } public double Wert2 { get; set; } ... }
MFG
Björn
- Als Antwort vorgeschlagen Stefan FalzModerator Sonntag, 22. Juni 2014 15:23
- Als Antwort markiert Thorsten84 Sonntag, 22. Juni 2014 18:16
-
ich denk mal er hat einfach nur vergessen den Rückgabe wert anzupassen
Wohl wahr. Hab ich übersehen. Danke für die Korrektur. Habs in meinem Posting jetzt auch angepasst.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Thorsten,
ist die Frage geklärt? Falls ja, wäre es prima, wenn Du die Antworten bewerten und ggfs. auch als Antwort markieren würdest.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo,
ich hätte da nochmal eine Frage, wollte aber kein extra Thema diesbezüglich eröffnen.
Im Grunde baut es auf dem jetzigen auf...Für die Klasse Result (siehe oben) berechne ich nun über ein numerisches Verfahren die Werte für die Differentiale in einer Schleife bis ein Max Wert erreicht ist.
Kann man diese Zwischenwerte von (x <= x_max) in einer Art Container zwischen speichern und später wieder aufrufen ?
-
Garantiert leider wird hier nicht ganz klar welche Klassenstruktur du hast.
Und was du genau zwischen speichern willst.
(x <= x_max) ist ja ein boolean. Du kannst zb. eine Membervariable in der Klasse Result einfügen und bei der Berechnung ihr den Wert zu ordnen. Bei Bedarf kannst du noch ein Property Verwenden mit dem du den Wert dann außerhalb der Klasse verwenden kannst.
class Result { bool _zwischenWert; public bool ZwischenWert { get { return _zwischenWert; } } public Ergebnis funktion1(double T, double xl) { Ergebnis ergebnis = new Ergebnis(); _zwischenWert = x <= X_max //Differentiale 'dx/dTwa' und 'dh/dTwa' ergebnis.Wert1 = 4.186 * Lambda ; ergebnis.Wert2 = 4.186 * Lambda ; return ergebnis; } }
Falls du nach einer anderen Lösung suchst. Müsstest du noch mal genauer erläutern was du möchtest.
MFG
Björn
-
Hallo,
ich habe Thorsten so verstanden, das er wärend der Berechnung einige Zwischenergebnisse erhält und diese gerne mit "aufbewahren" möchte.Die läuft eigentlich ganz ähnlich zu Björns Code, nur das du eine List<double> o.ä. verwenden solltest.
class Result{ public List<double> IntermediateResults{get;set;} public Result(){ this.IntermediateResults=new List<double>();//Neue Liste initialisieren } public double Result1{get;set;} //...usw. class Calculator{ public Result funktion1(double a,double b){ Result r = new Result(); //Berechne deine Werte und füge die Zwischenergebnisse hinzu: r.IntermediateResults.Add(12.345); r.Result1 = a+b;//Die Endergebnisse return r; } }
In dem zurück gegebenen Wert kannst du dann die Liste mit den Zwischenergebnissen (IntermediateResults) wieder abfragen und weiter verarbeiten. Die Ergebnisse bleiben solange erhalten, wie du die Rückgabe der Funktion in einer Variable aufhebst.
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert Thorsten84 Sonntag, 29. Juni 2014 14:50
-
Merci Tom! Das hab ich gesucht !
Sorry das ich erst jetzt Antworte und bewerte.... ich mach das in meiner Freizeit und komme nicht immer direkt dazu zu antworten.
Ich habe jetzt nochmal mit den Rückgabewerten rumgespielt und habe jetzt mit einem Array gearbeitet. Der Grund hierfür ist, dass ich mit einem System aus ODE's arbeite....d.h.
die Funktionen sind von einander abhängig in dem Rechenvorgang.
das sieht in etwa so aus:
y1 = (a*y1)/y2y2 = (b*y1)/y2
das Beispiel dazu siehst du hier:
{ public class Rechnen { public double[] Funktion(double a, double b) { double[] Calci; Calci = new double[2]; Calci[0] = a + Calci[1]; Calci[1] = a + Calci[0]; return Calci; } } public class Program { static void Main(string[] args) { Rechnen Test = new Rechnen(); double[] nummern; nummern = Test.Funktion(3, 5); Console.WriteLine("{0,3:F2}{1,10:F2}",nummern[0],nummern[1]); Console.ReadKey(); } } }
Funktioniert wunderbar. Das muss ich jetzt in diesen Block einarbeiten:
{ // Definition des Runge Kutta Rechenverfahrens class RungeKutta_Methode { public delegate double GetDerivative(double x, double y); GetDerivative getDerivative; double x0, y0, h; double d0; public RungeKutta_Methode(GetDerivative getDerivative, double x0, double y0, double h, double d0) { this.getDerivative = getDerivative; this.x0 = x0; this.y0 = y0; this.h = h; this.d0 = d0; } public int Step(out double x1, out double y1, out double d1) { double k1 = d0; double k2 = getDerivative(x0 + h / 2, y0 + h / 2 * k1); double k3 = getDerivative(x0 + h / 2, y0 + h / 2 * k2); double k4 = getDerivative(x0 + h, y0 + h * k3); y1 = y0 + h / 6 * (k1 + 2 * k2 + 2 * k3 + k4); x1 = x0 + h; d1 = getDerivative(x1, y1); x0 = x1; y0 = y1; d0 = d1; return 0; } } // Beschreibung des Rechenverfahrens und die Berechnungsvorschrift für den ersten Runge Kutta Schritt (Randbedindung) class Funktion { public double[] funktion(double x, double y) { double[] fun; fun = new double[1]; //double u = q / c; fun[1] = y + Math.Exp(x); return fun; } } class Program { static void Main(string[] args) { // Programmtest Funktion Test = new Funktion(); double x0 = 0; double x_max = 0.2; double y0 = 1; double h = 0.05; double[] i0; i0 = Test.funktion(x0, y0); RungeKutta_Methode integratorRK4D = new RungeKutta_Methode(Test.funktion, x0, y0, h, i0[1]); Console.WriteLine("TEST Funktion"); Console.WriteLine("x y y'"); Console.WriteLine("-------------------"); Console.WriteLine("{0,3:F2}{1,10:F6}", x0, y0); double x, y, i; do { integratorRK4D.Step(out x, out y, out i); Console.WriteLine("{0,3:F2}{1,10:F6}", x, y); } while (x < x_max); Console.WriteLine(); Console.ReadKey(); } } }
In der Klasse Funktion hab ich jetzt erstmal nur eine Gleichung [1] geschrieben.
Das Problem liegt bei
RungeKutta_Methode integratorRK4D = new RungeKutta_Methode(Test.funktion, x0, y0, h, i0[1]);
Hier sagt er mir, dass "Test.funktion" den falschen Rückgabetyp hat ?!
Ich stehe etwas auf dem Schlauch... :(
-
Hallo,
du hast den Delegaten wie folgt deklariert:public delegate double GetDerivative(double x, double y);
Deine Methode aber so:
public double[] Funktion(double a, double b)
Das passt natürlich nicht zusammen. Dein Delegat musst du somit auch an double[] anpassen. Beachte dann aber auch, dass du überall das Array von getDerivative zurück bekommst. So würde beispielsweise die Step-Methode nicht mehr richtig arbeiten, da d1 ein double-Parameter ist, aber ein double[] zugewiesen wird.
Tom Lambert - C# MVP
Bitte bewertet- und markiert Beiträge als Antwort. Danke.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hallo,
ergänzend zu Toms Antwort:
Anstatt neue Delegaten zu erzeugen - denn das ist eine vollständige Klasse, ist es in solchen Fällen sinnvoller mit den vorgefertigten generischen Delegaten zu arbeiten, hier z. B. mit // Definition des Runge Kutta Rechenverfahrens internal class RungeKutta_Methode { Func<double, double, double> getDerivative; double x0, y0, h; double d0; public RungeKutta_Methode(Func<double, double, double> getDerivative, double x0, double y0, double h, double d0) { this.getDerivative = getDerivative; this.x0 = x0; this.y0 = y0; this.h = h; this.d0 = d0; } public int Step(out double x1, out double y1, out double d1) { // ... ausgelassen ... } } // Beschreibung des Rechenverfahrens und die Berechnungsvorschrift für den ersten Runge Kutta Schritt (Randbedindung) class Funktion { // Statisch, da keine Instanzdaten notwendig public static double funktion(double x, double y) { return y + Math.Exp(x); } } // Ausschnittsweise aus Main: double i0 = i0 = Funktion.funktion(x0, y0); RungeKutta_Methode integratorRK4D = new RungeKutta_Methode(Funktion.funktion, x0, y0, h, i0);
Für Fälle ohne Rückgabe gäbe es Action<T>.
Nebenbei habe ich die Funktion.funktion (etwas unglückliche Namenswahl ;) in static geändert, so entfällt eine Instantiierung, die hier nicht notwendig ist, da es keine Variablen zu verwalten gibt - was ganz etwas schneller ist.
Alternativ kann man solche Funktionen auch als Lambda erzeugen und verwenden:
Func<double, double, double> myFunc = (double x, double y) => { return y + Math.Exp(x); }; double i0 = i0 = myFunc(x0, y0); RungeKutta_Methode integratorRK4D = new RungeKutta_Methode(myFunc, x0, y0, h, i0);
Was bei wechselnden Funktionen nützlich sein kann.
Gruß Elmar
P.S.: Zweiter (und letzter) Versuch, da vor zwei Stunden die Formatierung erbarmungslos zerschossen wurde ;(