diff --git a/src/FSharpx.Extras/ComputationExpressions/Option.fs b/src/FSharpx.Extras/ComputationExpressions/Option.fs index dc4b68fe..815b8eda 100644 --- a/src/FSharpx.Extras/ComputationExpressions/Option.fs +++ b/src/FSharpx.Extras/ComputationExpressions/Option.fs @@ -132,6 +132,12 @@ module Option = | Ok a -> Some a | _ -> None + /// Maps Unchecked object when null to None, otherwise Some value. + /// It's useful when getting data from external sources, pe. + let inline ofUnchecked (x: 'a when 'a : not struct) = + match box x with + | null -> None + | _ -> Some x /// Gets the value associated with the option or the supplied default value. let inline getOrElse v = diff --git a/tests/FSharpx.Tests/OptionTests.fs b/tests/FSharpx.Tests/OptionTests.fs index 74ccc1d8..c6027d50 100644 --- a/tests/FSharpx.Tests/OptionTests.fs +++ b/tests/FSharpx.Tests/OptionTests.fs @@ -94,3 +94,22 @@ let someIfBoolTestCases = [ [] let ``someIf with id`` (input:bool, expectedOutput:bool option) = Option.someIf id input |> shouldEqual expectedOutput + +type UncheckedRecordTest = + { Dummy: int } + +[] +let ``from unchecked value``() = + let test = { Dummy = 4 } + Assert.AreEqual(Some test, Option.ofUnchecked test) + Assert.AreEqual(None, Option.ofUnchecked (Unchecked.defaultof)) + +[] +type UncheckedRecordTest2 = + { Dummy2: int } + +[] +let ``from unchecked value without equality nor comparison``() = + let test = { Dummy2 = 4 } + Assert.AreEqual(Some test, Option.ofUnchecked test) + Assert.AreEqual(None, Option.ofUnchecked (Unchecked.defaultof)) \ No newline at end of file