none
Rückgabe von 2 Werten in einer Klasse RRS feed

  • 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

     

    Samstag, 21. Juni 2014 13:40

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


    Samstag, 21. Juni 2014 13:45
    Moderator
  • Hallo,
    grundsätzlich hast du 3 Möglichkeiten:

    1. 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".
    2. 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.
    3. 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
    Samstag, 21. Juni 2014 13:51
  • 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

    Samstag, 21. Juni 2014 18:12
  • 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
    Dienstag, 24. Juni 2014 21:16

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


    Samstag, 21. Juni 2014 13:45
    Moderator
  • Hallo,
    grundsätzlich hast du 3 Möglichkeiten:

    1. 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".
    2. 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.
    3. 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
    Samstag, 21. Juni 2014 13:51
  • 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

    Samstag, 21. Juni 2014 17:10
  • 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 ?

    Samstag, 21. Juni 2014 17:41
  • 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

    Samstag, 21. Juni 2014 18:12
  • das war es...perfekt! 

    Ich danke dir Björn

    Samstag, 21. Juni 2014 18:58
  • Naja die Lösung hat ja Stefan geliefert, ich denk mal er hat einfach nur vergessen  den Rückgabe wert anzupassen. (Markiere mal seine Antwort als Richtig)
    Samstag, 21. Juni 2014 19:04
  • 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

    Samstag, 21. Juni 2014 21:02
    Moderator
  • 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

    Sonntag, 22. Juni 2014 15:23
    Moderator
  • Hallo Stefan,

    ja ist mehr als zufriedenstellend beantwortet und vor allem sehr schnell.
    Tut mir Leid das die Bewertung / Markierung so spät kommt !

    Vielen Dank euch allen!

    Sonntag, 22. Juni 2014 18:18
  • 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 ?

    Dienstag, 24. Juni 2014 20:17
  • 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

    Dienstag, 24. Juni 2014 21:02
  • 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
    Dienstag, 24. Juni 2014 21:16
  • 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)/y2

    y2 = (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... :( 

    Sonntag, 29. Juni 2014 15:00
  • 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

    Sonntag, 29. Juni 2014 15:33
  • 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 ;(

    Sonntag, 29. Juni 2014 17:54