Importdeklarationen: Das open-Schlüsselwort

Eine Importdeklaration gibt ein Modul oder einen Namespace an, auf dessen Elemente Sie ohne Angabe eines vollqualifizierten Namens verweisen können.

Syntax

open module-or-namespace-name
open type type-name

Bemerkungen

Wenn Sie bei jedem Codeverweis den vollqualifizierten Namespace oder Modulpfad angeben, kann das die Übersichtlichkeit und Verwaltung des Codes beeinträchtigen. Stattdessen können Sie die open-Schlüsselwort für häufig verwendete Module und Namespaces verwenden, durch das Sie beim Verweisen auf ein Element dieses Moduls oder Namespaces anstelle des vollqualifizierten Namens die Kurzform des Namens verwenden können. Diese Schlüsselwort ähnelt dem using-Schlüsselwort in C#, using namespace in Visual C++ und Imports in Visual Basic.

Das angegebene Modul oder der angegebene Namespace muss sich im selben Projekt oder in einem Projekt oder einer Assembly befinden, auf das bzw. die verwiesen wird. Andernfalls können Sie einen Verweis auf das Projekt hinzufügen oder die Befehlszeilenoption -reference (oder deren Kurzform -r) verwenden. Weitere Informationen finden Sie unter Compileroptionen.

Die Importdeklaration stellt die Namen im Code zur Verfügung, der der Deklaration folgt, bis zum Ende des einschließenden Namespaces, Moduls oder der einschließenden Datei.

Wenn Sie mehrere Importdeklarationen verwenden, sollten diese sich in separaten Zeilen befinden.

Der folgende Code zeigt die Verwendung des open-Schlüsselworts, um Code zu vereinfachen.

// Without the import declaration, you must include the full
// path to .NET Framework namespaces such as System.IO.
let writeToFile1 filename (text: string) =
  let stream1 = new System.IO.FileStream(filename, System.IO.FileMode.Create)
  let writer = new System.IO.StreamWriter(stream1)
  writer.WriteLine(text)

// Open a .NET Framework namespace.
open System.IO

// Now you do not have to include the full paths.
let writeToFile2 filename (text: string) =
  let stream1 = new FileStream(filename, FileMode.Create)
  let writer = new StreamWriter(stream1)
  writer.WriteLine(text)

writeToFile2 "file1.txt" "Testing..."

Der F#-Compiler gibt keinen Fehler und keine Warnung aus, wenn Mehrdeutigkeiten auftreten, weil derselbe Name in mehreren geöffneten Modulen oder Namespaces auftritt. Wenn Mehrdeutigkeiten auftreten, gibt F# dem zuletzt geöffneten Modul oder Namespace den Vorzug. Beispielsweise bedeutet empty im folgenden Code Seq.empty, obwohl empty sich sowohl im Modul List als auch im Modul Seq befindet.

open List
open Seq
printfn %"{empty}"

Seien Sie daher vorsichtig, wenn Sie Module oder Namespaces wie List oder Seq öffnen, die Elemente mit identischen Namen enthalten. Erwägen Sie stattdessen die Verwendung der qualifizierten Namen. Sie sollten jede Situation vermeiden, in der der Code von der Reihenfolge der Importdeklarationen abhängig ist.

Offene Typdeklarationen

F# unterstützt open für einen Typ wie folgt:

open type System.Math
PI

Dadurch werden alle statischen Felder und Member des Typs verfügbar gemacht.

Sie können open auch für von F# definierte Datensatztypen und diskriminierte Union-Typen verwenden, um statische Member verfügbar zu machen. Bei diskriminierten Unions können Sie auch die Union-Fälle verfügbar machen. Dies kann hilfreich für den Zugriff auf Union-Fälle in einem Typ sein, der innerhalb eines Moduls deklariert ist, das Sie möglicherweise nicht öffnen möchten:

module M =
    type DU = A | B | C

    let someOtherFunction x = x + 1

// Open only the type inside the module
open type M.DU

printfn "%A" A

Standardmäßig offene Namespaces

Einige Namespaces werden so häufig in F#-Code verwendet, dass sie implizit offen sind, ohne dass eine explizite Importdeklaration erforderlich ist. In der folgenden Tabelle werden die Namespaces aufgeführt, die standardmäßig offen sind.

Namespace BESCHREIBUNG
FSharp.Core Enthält grundlegende F#-Typdefinitionen für integrierte Typen wie int und float
FSharp.Core.Operators Enthält grundlegende arithmetische Operationen wie + und *
FSharp.Collections Enthält unveränderliche Collectionklassen wie List und Array
FSharp.Control Enthält Typen für Steuerelementkonstrukte wie die verzögerte Auswertung und asynchrone Ausdrücke
FSharp.Text Enthält Funktionen für formatierte E/A, z. B. die printf-Funktion

AutoOpen-Attribut

Sie können das AutoOpen-Attribut auf eine Assembly anwenden, wenn Sie einen Namespace oder ein Modul automatisch öffnen möchten, wenn auf die Assembly verwiesen wird. Sie können das AutoOpen-Attribut auch auf ein Modul anwenden, um dieses Modul automatisch zu öffnen, wenn das übergeordnete Modul oder der übergeordnete Namespace geöffnet wird. Weitere Informationen finden Sie unter AutoOpenAttribute.

RequireQualifiedAccess-Attribut

Einige Module, Datensätze oder Union-Typen können das RequireQualifiedAccess-Attribut angeben. Wenn Sie auf Elemente dieser Module, Datensätze oder Unions verweisen, müssen Sie einen qualifizierten Namen verwenden, unabhängig davon, ob Sie eine Importdeklaration einschließen. Wenn Sie dieses Attribut gezielt für Typen verwenden, die häufig verwendete Namen definieren, können Sie Namenskonflikte vermeiden und dadurch den Code resilienter gegenüber Änderungen in Bibliotheken machen. Weitere Informationen finden Sie unter RequireQualifiedAccessAttribute.

Weitere Informationen