Dela via


Null-värden

Det här avsnittet beskriver hur null-värdet används i F#.

Null-värde

Null-värdet används normalt inte i F# för värden eller variabler. Null visas dock som ett onormalt värde i vissa situationer. Om en typ definieras i F#tillåts inte null som ett vanligt värde om inte attributet AllowNullLiteral tillämpas på typen. Om en typ definieras på något annat .NET-språk är null ett möjligt värde, och när du samverkar med sådana typer kan F#-koden stöta på null-värden.

För en typ som definierats i F# och används strikt från F#, är det enda sättet att skapa ett null-värde med hjälp av F#-biblioteket direkt att använda Unchecked.defaultof eller Array.zeroCreate. Men för en F#-typ som används från andra .NET-språk, eller om du använder den typen med ett API som inte är skrivet i F#, till exempel .NET Framework, kan null-värden inträffa.

Du kan använda option typen i F# när du kan använda en referensvariabel med ett möjligt null-värde på ett annat .NET-språk. I stället för null, med en F#- option typ, använder du alternativvärdet None om det inte finns något objekt. Du använder alternativvärdet Some(obj) med ett objekt obj när det finns ett objekt. Mer information finns i Alternativ. Observera att du fortfarande kan packa ett null värde i ett Alternativ om, för Some x, x råkar vara null. Därför är det viktigt att du använder None när ett värde är null.

Nyckelordet null är ett giltigt nyckelord i F#, och du måste använda det när du arbetar med .NET Framework-API:er eller andra API:er som är skrivna på ett annat .NET-språk. De två situationer där du kan behöva ett null-värde är när du anropar ett .NET-API och skickar ett null-värde som ett argument, och när du tolkar returvärdet eller en utdataparameter från ett .NET-metodanrop.

Om du vill skicka ett null-värde till en .NET-metod använder du bara nyckelordet null i den anropande koden. Följande kodexempel illustrerar detta.

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

Om du vill tolka ett null-värde som hämtas från en .NET-metod använder du mönstermatchning om du kan. Följande kodexempel visar hur du använder mönstermatchning för att tolka null-värdet som returneras från ReadLine när det försöker läsa förbi slutet av en indataström.

// 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
    ()

Null-värden för F#-typer kan också genereras på andra sätt, till exempel när du använder Array.zeroCreate, som anropar Unchecked.defaultof. Du måste vara försiktig med sådan kod för att behålla null-värdena inkapslade. I ett bibliotek som endast är avsett för F# behöver du inte söka efter null-värden i varje funktion. Om du skriver ett bibliotek för interoperation med andra .NET-språk kan du behöva lägga till kontroller för null-indataparametrar och utlösa en ArgumentNullException, precis som du gör i C# eller Visual Basic-kod.

Du kan använda följande kod för att kontrollera om ett godtyckligt värde är null.

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

Se även