From eb907882014352edcc3d37c3f8b684717fc13e26 Mon Sep 17 00:00:00 2001
From: albert-du <52804499+albert-du@users.noreply.github.com>
Date: Sun, 6 Mar 2022 11:32:12 -0800
Subject: [PATCH] NullReferenceException F# snippets
---
.../NullReferenceException/Overview/Array1.fs | 14 ++++++
.../NullReferenceException/Overview/Array2.fs | 12 +++++
.../NullReferenceException/Overview/Array3.fs | 14 ++++++
.../NullReferenceException/Overview/Array4.fs | 21 ++++++++
.../NullReferenceException/Overview/Chain1.fs | 48 +++++++++++++++++++
.../NullReferenceException/Overview/Chain2.fs | 46 ++++++++++++++++++
.../Overview/example1.fs | 23 +++++++++
.../Overview/example1a.fs | 6 +++
.../Overview/example2.fs | 22 +++++++++
.../NullReferenceException/Overview/fs.fsproj | 20 ++++++++
.../Overview/nullreturn2.fs | 26 ++++++++++
.../Overview/nullreturn2a.fs | 40 ++++++++++++++++
xml/System/NullReferenceException.xml | 11 +++++
13 files changed, 303 insertions(+)
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/Array1.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/Array2.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/Array3.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/Array4.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/Chain1.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/Chain2.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/example1.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/example1a.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/example2.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/fs.fsproj
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/nullreturn2.fs
create mode 100644 snippets/fsharp/System/NullReferenceException/Overview/nullreturn2a.fs
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/Array1.fs b/snippets/fsharp/System/NullReferenceException/Overview/Array1.fs
new file mode 100644
index 00000000000..f1d91f1dced
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/Array1.fs
@@ -0,0 +1,14 @@
+module Array1
+
+//
+open System
+
+let values = [| "one"; null; "two" |]
+for i = 0 to values.GetUpperBound 0 do
+ printfn $"""{values[i].Trim()}{if i = values.GetUpperBound 0 then "" else ", "}"""
+printfn ""
+// The example displays the following output:
+// Unhandled Exception:
+// System.NullReferenceException: Object reference not set to an instance of an object.
+// at .main()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/Array2.fs b/snippets/fsharp/System/NullReferenceException/Overview/Array2.fs
new file mode 100644
index 00000000000..3ebfa34c3fe
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/Array2.fs
@@ -0,0 +1,12 @@
+module Array2
+
+//
+open System
+
+let values = [| "one"; null; "two" |]
+for i = 0 to values.GetUpperBound 0 do
+ printf $"""{if values[i] <> null then values[i].Trim() else ""}{if i = values.GetUpperBound 0 then "" else ", "}"""
+Console.WriteLine()
+// The example displays the following output:
+// one, , two
+//
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/Array3.fs b/snippets/fsharp/System/NullReferenceException/Overview/Array3.fs
new file mode 100644
index 00000000000..7a92686c7bb
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/Array3.fs
@@ -0,0 +1,14 @@
+module Array3
+
+//
+let values: int[] = null
+for i = 0 to 9 do
+ values[i] <- i * 2
+
+for value in values do
+ printfn $"{value}"
+// The example displays the following output:
+// Unhandled Exception:
+// System.NullReferenceException: Object reference not set to an instance of an object.
+// at .main()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/Array4.fs b/snippets/fsharp/System/NullReferenceException/Overview/Array4.fs
new file mode 100644
index 00000000000..1c95768411b
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/Array4.fs
@@ -0,0 +1,21 @@
+module Array4
+
+//
+let values = Array.zeroCreate 10
+for i = 0 to 9 do
+ values[i] <- i * 2
+
+for value in values do
+ printfn $"{value}"
+// The example displays the following output:
+// 0
+// 2
+// 4
+// 6
+// 8
+// 10
+// 12
+// 14
+// 16
+// 18
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/Chain1.fs b/snippets/fsharp/System/NullReferenceException/Overview/Chain1.fs
new file mode 100644
index 00000000000..11f6751a2f5
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/Chain1.fs
@@ -0,0 +1,48 @@
+module Chain1
+
+//
+open System
+
+type Page() =
+ []
+ val mutable public URL: Uri
+ []
+ val mutable public Title: string
+
+type Pages() =
+ let pages = Array.zeroCreate 10
+ let mutable i = 0
+
+ member _.CurrentPage
+ with get () = pages[i]
+ and set (value) =
+ // Move all the page objects down to accommodate the new one.
+ if i > pages.GetUpperBound 0 then
+ for ndx = 1 to pages.GetUpperBound 0 do
+ pages[ndx - 1] <- pages[ndx]
+
+ pages[i] <- value
+ if i < pages.GetUpperBound 0 then
+ i <- i + 1
+
+ member _.PreviousPage =
+ if i = 0 then
+ if box pages[0] = null then
+ Unchecked.defaultof
+ else
+ pages[0]
+ else
+ i <- i - 1
+ pages[i + 1]
+
+let pages = Pages()
+if String.IsNullOrEmpty pages.CurrentPage.Title |> not then
+ let title = pages.CurrentPage.Title
+ printfn $"Current title: '{title}'"
+
+
+// The example displays the following output:
+// Unhandled Exception:
+// System.NullReferenceException: Object reference not set to an instance of an object.
+// at .main()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/Chain2.fs b/snippets/fsharp/System/NullReferenceException/Overview/Chain2.fs
new file mode 100644
index 00000000000..32fc63e7965
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/Chain2.fs
@@ -0,0 +1,46 @@
+module Chain2
+
+type Page() =
+ []
+ val mutable public URL: System.Uri
+ []
+ val mutable public Title: string
+
+type Pages() =
+ let pages = Array.zeroCreate 10
+ let mutable i = 0
+
+ member _.CurrentPage
+ with get () = pages[i]
+ and set (value) =
+ // Move all the page objects down to accommodate the new one.
+ if i > pages.GetUpperBound 0 then
+ for ndx = 1 to pages.GetUpperBound 0 do
+ pages[ndx - 1] <- pages[ndx]
+
+ pages[i] <- value
+ if i < pages.GetUpperBound 0 then
+ i <- i + 1
+
+ member _.PreviousPage =
+ if i = 0 then
+ if box pages[0] = null then
+ Unchecked.defaultof
+ else
+ pages[0]
+ else
+ i <- i - 1
+ pages[i + 1]
+
+//
+let pages = Pages()
+let current = pages.CurrentPage
+if box current <> null then
+ let title = current.Title
+ printfn $"Current title: '{title}'"
+else
+ printfn "There is no page information in the cache."
+// The example displays the following output:
+// There is no page information in the cache.
+//
+
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/example1.fs b/snippets/fsharp/System/NullReferenceException/Overview/example1.fs
new file mode 100644
index 00000000000..f4e5311329c
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/example1.fs
@@ -0,0 +1,23 @@
+module Example
+
+//
+open System
+
+[]
+let main args =
+ let value = Int32.Parse args[0]
+ // Set names to null, don't initialize it.
+ let mutable names = Unchecked.defaultof>
+ if value > 0 then
+ names <- ResizeArray()
+ names.Add "Major Major Major"
+ 0
+// Compilation does not display a warning as this is an extremely rare occurance in F#.
+// Creating a value without initalizing either requires using 'null' (not possible
+// on types defined in F# without []) or Unchecked.defaultof.
+//
+// The example displays output like the following output:
+// Unhandled Exception: System.NullReferenceException: Object reference
+// not set to an instance of an object.
+// at Example.main()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/example1a.fs b/snippets/fsharp/System/NullReferenceException/Overview/example1a.fs
new file mode 100644
index 00000000000..419ab5ebcc6
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/example1a.fs
@@ -0,0 +1,6 @@
+module example1a
+
+//
+let names = ResizeArray()
+names.Add "Major Major Major"
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/example2.fs b/snippets/fsharp/System/NullReferenceException/Overview/example2.fs
new file mode 100644
index 00000000000..bcec44fa7d8
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/example2.fs
@@ -0,0 +1,22 @@
+module example2
+
+//
+let populateNames (names: ResizeArray) =
+ let arrNames =
+ [ "Dakota"; "Samuel"; "Nikita"
+ "Koani"; "Saya"; "Yiska"; "Yumaevsky" ]
+ for arrName in arrNames do
+ names.Add arrName
+
+let getData () : ResizeArray =
+ null
+
+let names = getData ()
+populateNames names
+
+// The example displays output like the following:
+// Unhandled Exception: System.NullReferenceException: Object reference
+// not set to an instance of an object.
+// at Example.PopulateNames(List`1 names)
+// at .main()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/fs.fsproj b/snippets/fsharp/System/NullReferenceException/Overview/fs.fsproj
new file mode 100644
index 00000000000..7e9513604ee
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/fs.fsproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ net6.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2.fs b/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2.fs
new file mode 100644
index 00000000000..6b7609a57d5
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2.fs
@@ -0,0 +1,26 @@
+module nullreturn2
+
+//
+open System
+
+type Person(firstName) =
+ member _.FirstName = firstName
+
+ static member AddRange(firstNames) =
+ Array.map Person firstNames
+
+let persons =
+ [| "Abigail"; "Abra"; "Abraham"; "Adrian"
+ "Ariella"; "Arnold"; "Aston"; "Astor" |]
+ |> Person.AddRange
+
+let nameToFind = "Robert"
+let found = Array.Find(persons, fun p -> p.FirstName = nameToFind)
+
+printfn $"{found.FirstName}"
+
+// The example displays the following output:
+// Unhandled Exception: System.NullReferenceException:
+// Object reference not set to an instance of an object.
+// at .main()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2a.fs b/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2a.fs
new file mode 100644
index 00000000000..219d2d5fe6b
--- /dev/null
+++ b/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2a.fs
@@ -0,0 +1,40 @@
+module nullreturn2a
+
+//
+open System
+
+[]
+type Person(firstName) =
+ member _.FirstName = firstName
+
+ static member AddRange(firstNames) =
+ Array.map Person firstNames
+
+let persons =
+ [| "Abigail"; "Abra"; "Abraham"; "Adrian"
+ "Ariella"; "Arnold"; "Aston"; "Astor" |]
+ |> Person.AddRange
+
+let nameToFind = "Robert"
+let found = Array.Find(persons, fun p -> p.FirstName = nameToFind)
+
+if found <> null then
+ printfn $"{found.FirstName}"
+else
+ printfn $"{nameToFind} not found."
+
+// Using F#'s Array.tryFind function
+// This does not require a null check or []
+let found2 =
+ persons |> Array.tryFind (fun p -> p.FirstName = nameToFind)
+
+match found2 with
+| Some firstName ->
+ printfn $"{firstName}"
+| None ->
+ printfn $"{nameToFind} not found."
+
+// The example displays the following output:
+// Robert not found.
+// Robert not found.
+//
\ No newline at end of file
diff --git a/xml/System/NullReferenceException.xml b/xml/System/NullReferenceException.xml
index 2f995d90ca4..c52966e5174 100644
--- a/xml/System/NullReferenceException.xml
+++ b/xml/System/NullReferenceException.xml
@@ -66,21 +66,25 @@
- You've forgotten to instantiate a reference type. In the following example, `names` is declared but never instantiated:
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/example1.cs" id="Snippet1":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/example1.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/example1.vb" id="Snippet1":::
Some compilers issue a warning when they compile this code. Others issue an error, and the compilation fails. To address this problem, instantiate the object so that its value is no longer `null`. The following example does this by calling a type's class constructor.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/example1a.cs" id="Snippet2":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/example1a.fs" id="Snippet2":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/example1a.vb" id="Snippet2":::
- You've forgotten to dimension an array before initializing it. In the following example, `values` is declared to be an integer array, but the number of elements that it contains is never specified. The attempt to initialize its values therefore thrown a exception.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/Array3.cs" id="Snippet10":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/Array3.fs" id="Snippet10":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/Array3.vb" id="Snippet10":::
You can eliminate the exception by declaring the number of elements in the array before initializing it, as the following example does.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/Array4.cs" id="Snippet11":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/Array4.fs" id="Snippet11":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/Array4.vb" id="Snippet11":::
For more information on declaring and initializing arrays, see [Arrays](/dotnet/csharp/programming-guide/arrays/) and [Arrays](/dotnet/visual-basic/programming-guide/language-features/arrays/).
@@ -90,11 +94,13 @@
The code in the following example assumes that the method always returns `Person` object whose `FirstName` field matches a search string. Because there is no match, the runtime throws a exception.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/nullreturn2.cs" id="Snippet4":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2.fs" id="Snippet4":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/nullreturn2.vb" id="Snippet4":::
To address this problem, test the method's return value to ensure that it is not `null` before calling any of its members, as the following example does.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/nullreturn2a.cs" id="Snippet5":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/nullreturn2a.fs" id="Snippet5":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/nullreturn2a.vb" id="Snippet5":::
- You're using an expression (for example, you're chaining a list of methods or properties together) to retrieve a value and, although you're checking whether the value is `null`, the runtime still throws a exception. This occurs because one of the intermediate values in the expression returns `null`. As a result, your test for `null` is never evaluated.
@@ -102,11 +108,13 @@
The following example defines a `Pages` object that caches information about web pages, which are presented by `Page` objects. The `Example.Main` method checks whether the current web page has a non-null title and, if it does, displays the title. Despite this check, however, the method throws a exception.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/Chain1.cs" id="Snippet6":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/Chain1.fs" id="Snippet6":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/Chain1.vb" id="Snippet6":::
The exception is thrown because `pages.CurrentPage` returns `null` if no page information is stored in the cache. This exception can be corrected by testing the value of the `CurrentPage` property before retrieving the current `Page` object's `Title` property, as the following example does:
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/Chain2.cs" id="Snippet7":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/Chain2.fs" id="Snippet7":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/Chain2.vb" id="Snippet7":::
- You're enumerating the elements of an array that contains reference types, and your attempt to process one of the elements throws a exception.
@@ -114,16 +122,19 @@
The following example defines a string array. A `for` statement enumerates the elements in the array and calls each string's method before displaying the string.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/Array1.cs" id="Snippet8":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/Array1.fs" id="Snippet8":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/Array1.vb" id="Snippet8":::
This exception occurs if you assume that each element of the array must contain a non-null value, and the value of the array element is in fact `null`. The exception can be eliminated by testing whether the element is `null` before performing any operation on that element, as the following example shows.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/Array2.cs" id="Snippet9":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/Array2.fs" id="Snippet9":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/Array2.vb" id="Snippet9":::
- A exception is thrown by a method that is passed `null`. Some methods validate the arguments that are passed to them. If they do and one of the arguments is `null`, the method throws an exception. Otherwise, it throws a exception. The following example illustrates this scenario.
:::code language="csharp" source="~/snippets/csharp/System/NullReferenceException/Overview/example2.cs" id="Snippet3":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/NullReferenceException/Overview/example2.fs" id="Snippet3":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.nullreferenceexception.class/vb/example2.vb" id="Snippet3":::
To address this issue, make sure that the argument passed to the method is not `null`, or handle the thrown exception in a `try…catch…finally` block. For more information, see [Exceptions](/dotnet/standard/exceptions/).