diff --git a/snippets/fsharp/System/ValueType/Equals/fs.fsproj b/snippets/fsharp/System/ValueType/Equals/fs.fsproj
new file mode 100644
index 00000000000..f0a89cd967d
--- /dev/null
+++ b/snippets/fsharp/System/ValueType/Equals/fs.fsproj
@@ -0,0 +1,10 @@
+
+
+ Exe
+ net6.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/snippets/fsharp/System/ValueType/Equals/source.fs b/snippets/fsharp/System/ValueType/Equals/source.fs
new file mode 100644
index 00000000000..55a67a16b5a
--- /dev/null
+++ b/snippets/fsharp/System/ValueType/Equals/source.fs
@@ -0,0 +1,14 @@
+//
+type Complex() =
+ member val m_Re = 0. with get, set
+ member val m_Im = 0. with get, set
+
+ override this.Equals(ob) =
+ match ob with
+ | :? Complex as c ->
+ this.m_Re = c.m_Re && this.m_Im = c.m_Im
+ | _ -> false
+
+ override this.GetHashCode() =
+ this.m_Re.GetHashCode() ^^^ this.m_Im.GetHashCode()
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/ValueType/Overview/example1.fs b/snippets/fsharp/System/ValueType/Overview/example1.fs
new file mode 100644
index 00000000000..a64af5a5349
--- /dev/null
+++ b/snippets/fsharp/System/ValueType/Overview/example1.fs
@@ -0,0 +1,95 @@
+//
+open System
+open System.Numerics
+
+module Utility =
+ type NumericRelationship =
+ | GreaterThan = 1
+ | EqualTo = 0
+ | LessThan = -1
+
+ let isInteger (value: ValueType) =
+ match value with
+ | :? sbyte | :? int16 | :? int32 | :? int64
+ | :? byte | :? uint16 | :? uint32
+ | :? uint64 | :? bigint -> true
+ | _ -> false
+
+ let isFloat (value: ValueType) =
+ match value with
+ | :? float32 | :? float | :? decimal -> true
+ | _ -> false
+
+ let tryToBigInt (value: ValueType) =
+ match value with
+ | :? sbyte as v -> bigint v |> Some
+ | :? int16 as v -> bigint v |> Some
+ | :? int32 as v -> bigint v |> Some
+ | :? int64 as v -> bigint v |> Some
+ | :? byte as v -> bigint v |> Some
+ | :? uint16 as v -> bigint v |> Some
+ | :? uint32 as v -> bigint v |> Some
+ | :? uint64 as v -> bigint v |> Some
+ | :? float32 as v -> bigint v |> Some
+ | _ -> None
+
+ let isNumeric (value: ValueType) =
+ isInteger value || isFloat value
+
+ let compare (value1: ValueType) (value2: ValueType) =
+ if isNumeric value1 |> not then
+ invalidArg "value1" "value1 is not a number."
+ elif isNumeric value2 |> not then
+ invalidArg "value2" "value2 is not a number."
+
+ // Use BigInteger as common integral type
+ match tryToBigInt value1, tryToBigInt value2 with
+ | Some bigint1, Some bigint2 ->
+ BigInteger.Compare(bigint1, bigint2) |> enum
+
+ // At least one value is floating point use Double.
+ | _ ->
+ let dbl1 =
+ try
+ Convert.ToDouble value1
+ with
+ | :? OverflowException ->
+ printfn "value1 is outside the range of a Double."
+ 0.
+ | _ -> 0.
+
+ let dbl2 =
+ try
+ Convert.ToDouble value2
+ with
+ | :? OverflowException ->
+ printfn "value2 is outside the range of a Double."
+ 0.
+ | _ -> 0.
+
+ dbl1.CompareTo dbl2 |> enum
+//
+
+//
+printfn $"{Utility.isNumeric 12}"
+printfn $"{Utility.isNumeric true}"
+printfn $"{Utility.isNumeric 'c'}"
+printfn $"{Utility.isNumeric (DateTime(2012, 1, 1))}"
+printfn $"{Utility.isInteger 12.2}"
+printfn $"{Utility.isInteger 123456789}"
+printfn $"{Utility.isFloat true}"
+printfn $"{Utility.isFloat 12.2}"
+printfn $"{Utility.isFloat 12}"
+printfn $"{12.1} {Utility.compare 12.1 12} {12}"
+// The example displays the following output:
+// True
+// False
+// False
+// False
+// False
+// True
+// False
+// True
+// False
+// 12.1 GreaterThan 12
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/ValueType/Overview/fs.fsproj b/snippets/fsharp/System/ValueType/Overview/fs.fsproj
new file mode 100644
index 00000000000..f6fb5493c80
--- /dev/null
+++ b/snippets/fsharp/System/ValueType/Overview/fs.fsproj
@@ -0,0 +1,10 @@
+
+
+ Exe
+ net6.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/snippets/fsharp/System/ValueType/ToString/ToString2.fs b/snippets/fsharp/System/ValueType/ToString/ToString2.fs
new file mode 100644
index 00000000000..bf62cb070f7
--- /dev/null
+++ b/snippets/fsharp/System/ValueType/ToString/ToString2.fs
@@ -0,0 +1,23 @@
+//
+namespace Corporate.EmployeeObjects
+
+[]
+type EmployeeA =
+ val mutable Name : string
+
+[]
+type EmployeeB =
+ val mutable Name : string
+ override this.ToString() =
+ this.Name
+
+module Example =
+ let empA = EmployeeA(Name="Robert")
+ printfn $"{empA}"
+
+ let empB = EmployeeB(Name="Robert")
+ printfn $"{empB}"
+// The example displays the following output:
+// Corporate.EmployeeObjects.EmployeeA
+// Robert
+//
\ No newline at end of file
diff --git a/snippets/fsharp/System/ValueType/ToString/fs.fsproj b/snippets/fsharp/System/ValueType/ToString/fs.fsproj
new file mode 100644
index 00000000000..38faa650542
--- /dev/null
+++ b/snippets/fsharp/System/ValueType/ToString/fs.fsproj
@@ -0,0 +1,10 @@
+
+
+ Exe
+ net6.0
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xml/System/ValueType.xml b/xml/System/ValueType.xml
index a56cf22d1d3..b1a5436f707 100644
--- a/xml/System/ValueType.xml
+++ b/xml/System/ValueType.xml
@@ -66,11 +66,13 @@
Aside from serving as the base class for value types in the .NET Framework, the structure is generally not used directly in code. However, it can be used as a parameter in method calls to restrict possible arguments to value types instead of all objects, or to permit a method to handle a number of different value types. The following example illustrates how prevents reference types from being passed to methods. It defines a class named `Utility` that contains four methods: `IsNumeric`, which indicates whether its argument is a number; `IsInteger`, which indicates whether its argument is an integer; `IsFloat`, which indicates whether its argument is a floating-point number; and `Compare`, which indicates the relationship between two numeric values. In each case, the method parameters are of type , and reference types are prevented from being passed to the methods.
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Overview/example1.cs" id="Snippet1":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Overview/example1.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.valuetype.structure/vb/example1.vb" id="Snippet1":::
The following example illustrates calls to the methods of the `Utility` class.
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Overview/example1.cs" id="Snippet2":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Overview/example1.fs" id="Snippet2":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.valuetype.structure/vb/example1.vb" id="Snippet2":::
]]>
@@ -196,6 +198,7 @@
:::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR/ValueType.Equals Example/CPP/source.cpp" id="Snippet1":::
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Equals/source.cs" id="Snippet1":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Equals/source.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR/ValueType.Equals Example/VB/source.vb" id="Snippet1":::
]]>
@@ -266,6 +269,7 @@
:::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR/ValueType.Equals Example/CPP/source.cpp" id="Snippet1":::
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Equals/source.cs" id="Snippet1":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Equals/source.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR/ValueType.Equals Example/VB/source.vb" id="Snippet1":::
]]>
@@ -322,6 +326,7 @@
Value types defined by the `struct` keyword in C# and the `Structure`...`End Structure` construct in Visual Basic typically override the method to provide a more meaningful string representation of the value type. The following example illustrates the difference. It defines two value types, `EmployeeA` and `EmployeeB`, creates an instance of each, and calls its `ToString` method. Because the `EmployeeA` structure does not override the method, it displays only the fully qualified type name. The `EmployeeB.ToString` method, on the other hand, provides meaningful information about the object.
:::code language="csharp" source="~/snippets/csharp/System/ValueType/ToString/ToString2.cs" interactive="try-dotnet" id="Snippet1":::
+ :::code language="fsharp" source="~/snippets/fsharp/System/ValueType/ToString/ToString2.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/System.ValueType.ToString/vb/ToString2.vb" id="Snippet1":::
Note that, although enumeration types are also value types, they derive from the class, which overrides .