Teilen über


Nullwerte

In diesem Thema wird beschrieben, wie der Nullwert in F# verwendet wird.

Nullwerte vor F# 9

Der Nullwert wird in F# normalerweise nicht für Werte oder Variablen verwendet. Null wird jedoch in bestimmten Situationen als abnormer Wert angezeigt. Wenn ein Typ in F# definiert ist, ist NULL nicht als regulärer Wert zulässig, es sei denn, das AllowNullLiteral Attribut wird auf den Typ angewendet. Wenn ein Typ in einer anderen .NET-Sprache definiert ist, ist Null ein möglicher Wert, und wenn Sie mit solchen Typen zusammenarbeiten, kann ihr F#-Code null-Werte aufweisen.

Für einen Typ, der in F# definiert ist und ausschließlich von F# aus verwendet wird, ist die einzige Möglichkeit, einen NULL-Wert direkt mit der F#-Bibliothek zu erstellen, die Verwendung von Unchecked.defaultof oder Array.zeroCreate. Für einen F#-Typ, der von anderen .NET-Sprachen verwendet wird, oder wenn Sie diesen Typ mit einer API verwenden, die nicht in F# geschrieben ist, z. B. .NET Framework, können Nullwerte auftreten.

Sie können den option Typ in F# verwenden, wenn Sie möglicherweise eine Referenzvariable mit einem möglichen Nullwert in einer anderen .NET-Sprache verwenden. Anstelle von NULL verwenden Sie bei einem F#-option Typ den Optionswert None, wenn kein Objekt vorhanden ist. Sie verwenden den Optionswert Some(obj) mit einem Objekt obj, wenn ein Objekt vorhanden ist. Weitere Informationen finden Sie unter Optionen. Beachten Sie, dass Sie einen null-Wert trotzdem in eine Option packen können, wenn es bei Some xder Fall ist, dass xnullist. Aus diesem Grund ist es wichtig, dass Sie None verwenden, wenn ein Wert nullist.

Das schlüsselwort null ist ein gültiges Schlüsselwort in F#, und Sie müssen es verwenden, wenn Sie mit .NET Framework-APIs oder anderen APIs arbeiten, die in einer anderen .NET-Sprache geschrieben sind. Die beiden Situationen, in denen Sie möglicherweise einen NULL-Wert benötigen, sind, wenn Sie eine .NET-API aufrufen und einen Nullwert als Argument übergeben, und wenn Sie den Rückgabewert oder einen Ausgabeparameter aus einem .NET-Methodenaufruf interpretieren.

Um einen NULL-Wert an eine .NET-Methode zu übergeben, verwenden Sie einfach das schlüsselwort null im aufrufenden Code. Im folgenden Codebeispiel wird dies veranschaulicht.

open System

// Pass a null value to a .NET method.
let ParseDateTime (str: string) =
    let (success, res) =
        DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal)

    if success then Some(res) else None

Wenn Sie einen Nullwert interpretieren möchten, der von einer .NET-Methode abgerufen wird, verwenden Sie, wenn möglich, Mustervergleich. Im folgenden Codebeispiel wird gezeigt, wie Sie den Musterabgleich verwenden, um den Nullwert zu interpretieren, der von ReadLine zurückgegeben wird, wenn versucht wird, über das Ende eines Eingabedatenstroms hinaus zu lesen.

// Open a file and create a stream reader.
let fileStream1 =
    try
        System.IO.File.OpenRead("TextFile1.txt")
    with :? System.IO.FileNotFoundException ->
        printfn "Error: TextFile1.txt not found."
        exit (1)

let streamReader = new System.IO.StreamReader(fileStream1)

// ProcessNextLine returns false when there is no more input;
// it returns true when there is more input.
let ProcessNextLine nextLine =
    match nextLine with
    | null -> false
    | inputString ->
        match ParseDateTime inputString with
        | Some(date) -> printfn "%s" (date.ToLocalTime().ToString())
        | None -> printfn "Failed to parse the input."

        true

// A null value returned from .NET method ReadLine when there is
// no more input.
while ProcessNextLine(streamReader.ReadLine()) do
    ()

Nullwerte für F#-Typen können auch auf andere Weise generiert werden, z. B. wenn Sie Array.zeroCreateverwenden, die Unchecked.defaultofaufruft. Sie müssen mit diesem Code vorsichtig sein, damit die NULL-Werte gekapselt bleiben. In einer Bibliothek, die nur für F# vorgesehen ist, müssen Sie in jeder Funktion nicht auf Nullwerte überprüfen. Wenn Sie eine Bibliothek für die Interoperabilität mit anderen .NET-Sprachen schreiben, müssen Sie möglicherweise Überprüfungen auf NULL-Eingabeparameter hinzufügen und eine ArgumentNullExceptionauslösen, genau wie in C#- oder Visual Basic-Code.

Sie können den folgenden Code verwenden, um zu überprüfen, ob ein beliebiger Wert null ist.

match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."

Nullwerte beginnend mit F# 9

In F# 9 werden der Sprache zusätzliche Funktionen hinzugefügt, um Mit Verweistypen zu umgehen, die null als Wert aufweisen können. Diese sind standardmäßig deaktiviert – um sie zu aktivieren, muss die folgende Eigenschaft in Der Projektdatei abgelegt werden:

<Nullable>enable</Nullable>

Dadurch wird das --checknulls+-Flag an den F#-Compiler übergeben und eine NULLABLE-Präprozessor-Direktive für den Build-Prozess festgelegt.

Um explizit die Nullierbarkeit zu aktivieren, muss eine Typdeklaration mit der neuen Syntax suffixiert werden:

type | null

Das Balkensymbol | hat in der Syntax die Bedeutung eines logischen ODERs, das eine Vereinigung von zwei disjunkten Sets von Typen festlegt: den zugrundeliegenden Typ und die löschbare Referenz. Dies ist dasselbe syntaktische Symbol, das zum Deklarieren mehrerer Fälle einer F#-diskriminierten Vereinigung verwendet wird: type AB = A | B hat entweder die Bedeutung von Aoder B.

Die nullable Annotation | null kann an allen Stellen verwendet werden, an denen normalerweise ein Referenztyp verwendet werden würde:

  • Felder von Union-Typen, Record-Typen und angepasste Typen.
  • Geben Sie Aliase für vorhandene Typen ein.
  • Typanwendungen eines generischen Typs.
  • Explizite Typ-Annotation, um Bindungen, Parameter oder Rückgabetypen zuzulassen.
  • Geben Sie Anmerkungen zu Objektprogrammierungskonstrukten wie Membern, Eigenschaften oder Feldern ein.
type AB = A | B
type AbNull = AB | null

type RecordField = { X: string | null }
type TupleField = string * string | null

type NestedGenerics = { Z : List<List<string | null> | null> | null }

Das Balkensymbol | hat andere Verwendungen in F#, die zu syntaktischen Mehrdeutigkeiten führen können. In solchen Fällen werden Klammern um den null-annotierten Typ benötigt.

// Unexpected symbol '|' (directly before 'null') in member definition
type DUField = N of string | null

Durch das Umschließen desselben Typs in ein Paar von ( ) Klammern wird das Problem behoben:

type DUField = N of (string | null)

Bei Verwendung im Musterabgleich wird | verwendet, um verschiedene Musterabgleichsklauseln zu trennen.

match x with
| ?: string | null -> ...

Dieser Codeausschnitt entspricht tatsächlich dem Code, der zuerst einen Typtest mit dem string Typ durchführt und dann eine separate Klausel für die Behandlung von NULL aufweist:

match x with
| ?: string 
| null -> ...

Wichtig

Die zusätzlichen NULL-bezogenen Funktionen wurden der Sprache für die Interoperabilitätszwecke hinzugefügt. Die Verwendung von | null in der F#-Typmodellierung wird nicht als idiomatisch betrachtet, um fehlende Informationen zu kennzeichnen – verwenden Sie zu diesem Zweck Optionen (wie oben beschrieben). Lesen Sie mehr über Null-bezogene Konventionen im Style Guide.

Siehe auch