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 .