Exemplarische Vorgehensweise: Erstellen, Debuggen und Bereitstellen einer Anwendung mit Visual F#

Diese exemplarische Vorgehensweise bringt Ihnen die Verwendung von F# in Visual Studio 2010 mit .NET Framework 4 näher.

In dieser exemplarischen Vorgehensweise erfahren Sie anhand einer historischen Analyse von Zinssatzdaten des US-Finanzministeriums, wie Sie mithilfe von Visual Studio 2010 F#-Anwendungen erstellen. Wir beginnen mit einigen einfachen Datenanalysen, die im interaktiven Fenster von F# durchgeführt werden. Anschließend beschäftigen wir uns mit dem Schreiben und Testen von Code zur Datenanalyse. Schließlich fügen wir ein C#-Front-End hinzu, mit dem die Integration des F#-Codes in andere .NET-Sprachen vorgenommen wird.

Vorbereitungsmaßnahmen

Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgenden Komponenten:

  • Visual Studio 2010

Tipp

Ihr Computer zeigt möglicherweise für einige der Elemente der Visual Studio-Benutzeroberfläche in der folgenden Anleitung andere Namen oder Standorte an. Diese Elemente sind von der jeweiligen Visual Studio-Version und den verwendeten Einstellungen abhängig. Weitere Informationen finden Sie unter Visual Studio-Einstellungen.

So erstellen Sie ein F#-Skript

  1. Erstellen Sie zunächst ein F#-Skript. Zeigen Sie im Menü Datei auf Neu, und klicken Sie auf Datei. Wählen Sie im Dialogfeld Neue Datei in der Liste Installierte Vorlagen die Option Skript aus, und wählen Sie anschließend F#-Skriptdatei aus. Klicken Sie auf Öffnen, um die Datei zu erstellen, und speichern Sie die Datei unter der Bezeichnung RateAnalysis.fsx.

  2. Greifen Sie mithilfe von .NET- und F#-APIs auf Daten von der Website der amerikanischen Zentralbank zu. Geben Sie den folgenden Code ein.

    open System.Net
    open System.IO
    
    let url = sprintf "http://www.federalreserve.gov/releases/h15/data/business_day/H15_TCMNOM_Y10.txt"
    let req = WebRequest.Create(url, Timeout = 10000000)
    let resp = req.GetResponse()
    let stream = resp.GetResponseStream()
    let reader = new StreamReader(stream)
    let csv = reader.ReadToEnd()
    

    Beachten Sie Folgendes:

    • Zeichenfolgen und Schlüsselwörter werden farbig hervorgehoben.

    • Nach dem Eingeben der einzelnen Punkte (.) werden Vervollständigungslisten angezeigt.

    • Sie können Methodennamen und andere Bezeichner von Visual Studio vervollständigen lassen. Verwenden Sie hierzu in der Mitte eines Bezeichners die Tastenkombinationen STRG+LEERTASTE oder STRG+J. Bei der Verwendung von STRG+J wird eine Vervollständigungsliste angezeigt.

    • Zeigen Sie mit dem Cursor auf einen Bezeichner im Code, um eine QuickInfo mit Informationen zu diesem Bezeichner anzuzeigen.

    • Befindet sich der Cursor über WebRequest und drücken Sie dann F1, wird die entsprechende Dokumentation angezeigt.

    • Befindet sich der Cursor über let und drücken Sie dann F1, wird die entsprechende Dokumentation angezeigt.

    • Auf Typen und Namespaces von mscorlib.dll, System.dll und System.Windows.Forms.dll wird standardmäßig verwiesen.

    • Der hier festgelegte Timeout-Wert ist eine Eigenschaft, kein Konstruktorargument. Mit F# können Sie Eigenschaftswerte auf diese Weise festlegen.

    • Wenn Sie die Beispiel-URL in einen Browser kopieren, erhalten Sie eine Reihe von durch Trennzeichen getrennte Daten- und Zinssatzwerte, die von der amerikanischen Zentralbank veröffentlicht wurden.

  3. Jetzt wird der Code mit F# Interactive ausgeführt. Markieren Sie mithilfe der Maus oder der Tastenkombination STRG+A den gesamten Code, klicken Sie anschließend mit der rechten Maustaste, und wählen Sie Senden an Interactive aus. Alternativ können Sie die Tastenkombination ALT+EINGABETASTE verwenden.

    • Das Fenster "F# Interactive" wird geöffnet, sofern es nicht bereits angezeigt wurde.

    • Der Code wird erfolgreich ausgeführt.

    • Im Fenster "F# Interactive" wird Folgendes angezeigt.

      val url : string =
        "http://www.federalreserve.gov/releases/h15/data/business_day/"+[18 chars]
      val req : System.Net.WebRequest
      val resp : System.Net.WebResponse
      val stream : System.IO.Stream
      val reader : System.IO.StreamReader
      val csv : string =
        "  ,Instrument,"U.S. government securities/Treasury constant m"+[224452 chars]
      
      >
      
  4. Überprüfen Sie anschließend die Daten mit F# Interactive. Geben Sie in die Eingabeaufforderung von F# Interactive csv;; ein, und drücken Sie die EINGABETASTE. Geben Sie csv.Length ein;;, und drücken Sie die EINGABETASTE. Beachten Sie Folgendes:

    • Die Daten sind aktuell.

    • F# Interactive zeigt den Wert der Zeichenfolge csv und seine Länge an.

      07/10/2009, 3.32
      07/13/2009, 3.38
      07/14/2009, 3.50
      07/15/2009, 3.63
      "
      > csv.Length;;
      val it : int = 224513
      
    • Die folgende Abbildung zeigt das F# Interactive-Fenster.

      F# Interactive-Fenster

      F# Interactive-Fenster

  5. Jetzt erstellen wir F#-Code zur Analyse von CSV (durch Trennzeichen getrennte Werte)-Daten. Eine CSV-Datei wird so genannt, da die in ihr enthaltenen Werte durch Trennzeichen getrennt sind. Fügen Sie im Code-Editor folgenden Code hinzu: Wählen Sie beim Hinzufügen der einzelnen Zeilen den Code aus, der in diesem Abschnitt bis zur Zeile hinzugefügt wurde, und drücken Sie ALT+EINGABE, um die partiellen Ergebnisse anzuzeigen. Beachten Sie Folgendes:

    • Nach der Eingabe eines Punkts erhalten Sie selbst in der Mitte von komplexen geschachtelten Ausdrücken von IntelliSense hilfreiche Informationen.

    • Ist der Code unvollständig (oder falsch), wird durch rote wellenförmige Unterstreichung angezeigt, dass Syntaktik- und Semantikfehler im Code auftreten.

    • Pipelines werden mit dem Pipeoperator (|>) erstellt. Der Pipeoperator verwendet den Rückgabewert eines Ausdrucks als Argument für die Funktion auf der nächsten Zeile. Pipelines und F# Interactive ermöglichen die einfache partielle Ausführung von Datenverarbeitungscodes.

    let interest = 
        csv.Split([|'\n'|])
        |> Seq.skip 8
        |> Seq.map (fun line -> line.Trim())
        |> Seq.filter (fun line -> not (line.EndsWith("ND")))
        |> Seq.filter (fun line -> not (line.Length = 0))
        |> Seq.map (fun line -> line.Split([|','|]))
        |> Seq.map ( fun values ->
            System.DateTime.Parse(values.[0]),
            float values.[1])
    
  6. Jetzt erhält diese Funktionalität einen Namen. Entfernen Sie 10 aus der Definition der url, und ersetzen Sie den Wert durch %d, um das Zeichenfolgenliteral in eine Formatzeichenfolge zu verwandeln. Fügen Sie nach der Formatzeichenfolge maturity hinzu. Wählen Sie bis auf diese einzelne neue Zeile den gesamten Code aus, und drücken Sie TAB. Fügen Sie über dem eingezogenen Codeblock let loadRates maturity = hinzu. Fügen Sie am Ende des eingezogenen Blocks interest hinzu. Beachten Sie Folgendes:

    Der Code sieht nun folgendermaßen aus:

    open System.Net
    open System.IO
    
    let loadRates maturity = 
        let url = sprintf "http://www.federalreserve.gov/releases/h15/data/business_day/H15_TCMNOM_Y%d.txt" maturity
        let req = WebRequest.Create(url, Timeout = 10000000)
        let resp = req.GetResponse()
        let stream = resp.GetResponseStream()
        let reader = new StreamReader(stream)
        let csv = reader.ReadToEnd()
    
        let interest = 
            csv.Split([|'\n'|])
            |> Seq.skip 8
            |> Seq.map (fun line -> line.Trim())
            |> Seq.filter (fun line -> not (line.EndsWith("ND")))
            |> Seq.filter (fun line -> not (line.Length = 0))
            |> Seq.map (fun line -> line.Split([|','|]))
            |> Seq.map ( fun values ->
                System.DateTime.Parse(values.[0]),
                float values.[1])
        interest
    
  7. Jetzt verwenden wir diese Funktionalität für neue Eingaben. Wählen Sie den ganzen Code aus, und drücken Sie ALT+EINGABE, um ihn mit F# Interactive auszuführen. Rufen Sie über die F# Interactive-Eingabeaufforderung die neue loadRates-Funktion für andere Reiferaten auf: 1, 2 und 5 (in Jahren). Beachten Sie Folgendes:

    • Vorherige Definitionen gehen in F# Interactive nicht verloren, aber neue Definitionen sind verfügbar.

    • Komplexe strukturierte Daten werden mithilfe einer speziellen Druckfunktion gerendert.

So entwickeln Sie eine Komponente mit F#

  • Erstellen Sie ein Bibliotheksprojekt, um die erstellte Funktion bereitzustellen. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt. Wählen Sie im Dialogfeld Neues Projekt in der Liste Installierte Vorlagen die Option Visual F# und anschließend F#-Bibliothek aus, um ein neues Bibliotheksprojekt zu erstellen. Geben Sie dem Projekt den Namen RateAnalysis. Kopieren Sie den Code, den Sie zuvor aus RateAnalysis.fsx erstellt haben, und fügen Sie ihn in Module1.fs ein. Ändern Sie die Moduldeklaration in Module1.fs von Modul Module1 in Modul RateLoader um. Benennen Sie im Projektmappen-ExplorerModule1.fs in RateLoader.fs um. Beachten Sie Folgendes:

    • Die standardmäßige F#-Bibliothek-Vorlage stellt eine Codedatei mit der Erweiterung .fs und ein Skript mit der Erweiterung .fsx bereit. Sie können die Skriptdatei zum interaktiven Testen des Bibliothekscodes verwenden.

Die folgende Abbildung zeigt das Dialogfeld Neues Projekt mit mehreren verfügbaren Optionen für F# an. Die F#-Bibliothek-Projektvorlage wird ausgewählt.

F#-Vorlagenoptionen

Dialogfeld "Neues Projekt" mit ausgewählter F#-Bibliothek

  1. Jetzt erstellen wir eine F#-Klasse, die die gewünschte Funktionalität bereitstellt. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, zeigen Sie auf Hinzufügen und klicken Sie dann auf Neues Element. Wählen Sie im Dialogfeld Neues Element hinzufügen die Option für die F#-Quelldatei aus. Benennen Sie die Datei Analyzer.fs. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Script.fsx, und klicken Sie anschließend auf Nach unten. Alternativ können Sie die Tastenkombination ALT+NACH-UNTEN verwenden. Fügen Sie folgenden Code in Analyzer.fs ein:

    module RateAnalysis.Analyzer
    
    open RateLoader
    
    /// Provides analysis of historical interest rate data.
    type Analyzer(ratesAndDates) = 
        let rates = 
            ratesAndDates
            |> Seq.map snd
    
        /// Construct Analyzer objects for each maturity category.
        static member GetAnalyzers(maturities) = 
            maturities
            |> Seq.map loadRates
            |> Seq.map (fun ratesAndDates -> new Analyzer(ratesAndDates))
    
        member sa.Min =
            let date, minRate = (Seq.minBy (fun (_, rate) -> rate) ratesAndDates)
            (minRate, date.ToString("d"))
    
        member sa.Max = 
            let date, maxRate = (Seq.maxBy (fun (_, rate) -> rate) ratesAndDates)
            (maxRate, date.ToString("d"))
    
        member sa.Current =
            rates |> List.ofSeq |> List.rev |> List.head 
    

    Beachten Sie Folgendes:

    • F# unterstützt objektorientierte Programmierungskonzepte. Weitere Informationen finden Sie in Klassen (F#), Vererbung (F#) und in anderen relevanten Themen der F#-Sprachreferenz.
  2. Als nächstes generieren wir XML-Dokumentationskommentare. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und klicken Sie dann auf Eigenschaften. Aktivieren Sie auf der Registerkarte Erstellen am unteren Rand der Seite das Kontrollkästchen XML-Dokumentationsdatei. Beachten Sie Folgendes:

    • XML-Dokumentation kann für jede F#-Assembly generiert werden.

    • Standardmäßig wird XML-Dokumentation im Ausgabepfad generiert.

  3. Drücken Sie STRG+UMSCHALT+B oder F6, um das Projekt zu erstellen. Beachten Sie Folgendes:

    • Das Projekt wird erfolgreich erstellt.

    • Im Fehlerlistenfenster werden keine Fehler angezeigt.

    • Das Ausgabeverzeichnis enthält .dll, .pdb- und .xml-Dateien.

    • Im Ausgabefenster wird Folgendes angezeigt:

      ------ Build started: Project: RateAnalysis, Configuration: Debug Any CPU ------
          C:\Program Files (x86)\Microsoft F#\v4.0\fsc.exe -o:obj\Debug\RateAnalysis.exe -g --debug:full --noframework --define:DEBUG --define:TRACE --optimize- --tailcalls- -r:"C:\Program Files (x86)\Microsoft F#\v4.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths --flaterrors Program.fs RateLoader.fs ValueAnalyzer.fs 
          RateAnalysis -> C:\Users\ghogen\Documents\Visual Studio 10\Projects\RateAnalysis\RateAnalysis\bin\Debug\RateAnalysis.exe
      ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
      
  4. Klicken Sie mit der rechten Maustaste auf den Lösungsknoten, zeigen Sie auf Hinzufügen, und klicken Sie dann auf Neues Projekt, um eine C#-Clientanwendung hinzuzufügen. Wählen Sie im Dialogfeld Neues Projekt hinzufügen in der Liste Installierte Vorlagen die Option Visual C# aus, und klicken Sie anschließend auf Konsolenanwendung. Möglicherweise muss der Knoten Andere Sprachen erweitert werden. Nennen Sie das Projekt CSharpDriver. Klicken Sie mit der rechten Maustaste auf den Knoten Verweise des Projekts, und klicken Sie auf Verweis hinzufügen. Klicken Sie im Dialogfeld Verweis hinzufügen auf der Registerkarte Projekte auf RateAnalysis, und klicken Sie anschließend auf OK. Klicken Sie mit der rechten Maustaste auf den Projektknoten CSharpDriver, und klicken Sie auf Als Startprojekt festlegen. Geben Sie den folgenden Code in den Text der Main-Methode der C#-Anwendung ein. Beachten Sie Folgendes:

    • Sie können in C# und F# Verweise zwischen Projekten hinzufügen.

    • In F# definierte Namespaces und Typen können wie andere Typen ebenfalls in C# verarbeitet werden.

    • F#-Dokumentationskommentare sind in C# IntelliSense verfügbar.

    • C# kann auf Tupelrückgabewerte der F#-API zugreifen. Die Tupel sind Tuple-Werte in .NET Framework 4.

    var maturities = new[] { 1, 2, 5, 10 };
    var analyzers = RateAnalysis.Analyzer.Analyzer.GetAnalyzers(maturities);
    
    foreach (var item in analyzers)
    {
        Console.WriteLine("Min = {0}, \t Max = {1}, \t Current = {2}", item.Min, item.Max, item.Current);
    }
    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
    
  5. So debuggen Sie die Anwendung: Drücken Sie F11, um die Anwendung zu erstellen, starten Sie die Anwendung im Debugger, und navigieren Sie zur ersten Zeile des ausgeführten Codes. Drücken Sie so oft F11, bis Sie zum F#-Code im Text des GetAnalyzers-Members gelangen. Beachten Sie Folgendes:

    • Sie können leicht vom F#- zum C#-Code wechseln.

    • Jeder Ausdruck in F# stellt einen Schritt im Debugger dar.

    • Das Lokalfenster zeigt die Werte von maturities an.

    • Drücken Sie wiederholt F11, um durch die Auswertung für den Rest der Anwendung zu springen.

    • Debuggerbefehle, wie Ausführen bis Cursor, Nächste Anweisung festlegen, Haltepunkt einfügen, Überwachung hinzufügen oder Gehe zu Disassembly, funktionieren wie erwartet.

So stellen Sie eine F#-Anwendung bereit:

  1. In diesem Schritt legen wir das Projekt auf eine andere Version von .NET Framework fest. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das F# RateAnalysis-Projekt, und klicken Sie dann auf Eigenschaften. Legen Sie auf der Registerkarte Anwendung die Einstellung Zielframework auf .NET Framework 3.5. fest. Beachten Sie Folgendes:

    • Mit F# können Sie auf verschiedene Versionen von .NET Framework abzielen.

    • Das Ändern des Zielframeworks erfordert das erneute Laden des Projekts.

    • Nachdem Sie das Zielframework geändert haben, sind einige Assemblyverweise nicht mehr im Dialogfeld Verweis hinzufügen aktiviert und nicht verfügbar.

  2. Im C#-Projekt muss auf die Version der FSharp.Core-Assembly verwiesen werden, die auf .NET Framework 2.0 abzielt. Sie sollte auch verwendet werden, wenn Sie auf die Versionen 3.0 oder 3.5 von .NET Framework abzielen. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten Verweise, und klicken Sie anschließend auf Verweis hinzufügen. Wählen Sie auf der Registerkarte .NET FSharp.Core, Version 2.0.0.0, aus. Klicken Sie dann auf OK. Generieren Sie die Projektmappe neu.

  3. Um die erforderlichen Komponenten festzulegen, doppelklicken Sie in CSharpDriver auf den Knoten Eigenschaften. Klicken Sie auf der Registerkarte Veröffentlichen auf die Schaltfläche Erforderliche Komponenten und, aktivieren Sie im Dialogfeld Erforderliche Komponenten das Kontrollkästchen für Microsoft Visual F#-Laufzeit für .NET 2.0. Beachten Sie Folgendes:

    • Das Laufzeitpaket von F# ist von .NET Framework getrennt.

    • Bei der Bereitstellung von Anwendungen, die F# verwenden, muss dieses Laufzeitpaket explizit als erforderliche Komponente hinzugefügt werden.

    • Zwei Laufzeitpakete sind verfügbar: die Version 2.0 für .NET Framework, Version 2.0, 3.0 und 3.5, und die Version 4.0 für .NET Framework 4.

  4. Stellen Sie die C#-Anwendung mit ClickOnce bereit. Klicken Sie mit der rechten Maustaste auf das CSharpDriver-Projekt, und klicken Sie anschließend auf Veröffentlichen. Klicken Sie im Webpublishing-Assistenten auf Fertig stellen. Führen Sie die entstandene CSharpDriver-Anwendung aus. Beachten Sie Folgendes:

    • Das Visual F#-Laufzeitpaket ist in der Anwendung enthalten.

    • Durch Ausführen der Anwendung wird das F#-Laufzeitpaket installiert und die Anwendung erfolgreich ausgeführt.

Nächste Schritte

Informationen zu den ersten Schritten im F#-Code erhalten Sie unter Exemplarische Vorgehensweise: Ihr erstes F#-Programm, oder lesen Sie Funktionen als erstrangige Werte (F#), um mehr über die Funktionen in F# zu erfahren. Lesen Sie die F#-Sprachreferenz, um ausführliche Informationen über die F#-Programmiersprache zu erhalten.

Siehe auch

Weitere Ressourcen

Exemplarische Vorgehensweisen für Visual F#

Beispiele und exemplarische Vorgehensweisen (F#)