Skip to content

Commit d377a71

Browse files
authored
ValueType F# snippets (dotnet#8073)
1 parent 7d60e21 commit d377a71

File tree

7 files changed

+167
-0
lines changed

7 files changed

+167
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="source.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//<snippet1>
2+
type Complex() =
3+
member val m_Re = 0. with get, set
4+
member val m_Im = 0. with get, set
5+
6+
override this.Equals(ob) =
7+
match ob with
8+
| :? Complex as c ->
9+
this.m_Re = c.m_Re && this.m_Im = c.m_Im
10+
| _ -> false
11+
12+
override this.GetHashCode() =
13+
this.m_Re.GetHashCode() ^^^ this.m_Im.GetHashCode()
14+
//</snippet1>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// <Snippet1>
2+
open System
3+
open System.Numerics
4+
5+
module Utility =
6+
type NumericRelationship =
7+
| GreaterThan = 1
8+
| EqualTo = 0
9+
| LessThan = -1
10+
11+
let isInteger (value: ValueType) =
12+
match value with
13+
| :? sbyte | :? int16 | :? int32 | :? int64
14+
| :? byte | :? uint16 | :? uint32
15+
| :? uint64 | :? bigint -> true
16+
| _ -> false
17+
18+
let isFloat (value: ValueType) =
19+
match value with
20+
| :? float32 | :? float | :? decimal -> true
21+
| _ -> false
22+
23+
let tryToBigInt (value: ValueType) =
24+
match value with
25+
| :? sbyte as v -> bigint v |> Some
26+
| :? int16 as v -> bigint v |> Some
27+
| :? int32 as v -> bigint v |> Some
28+
| :? int64 as v -> bigint v |> Some
29+
| :? byte as v -> bigint v |> Some
30+
| :? uint16 as v -> bigint v |> Some
31+
| :? uint32 as v -> bigint v |> Some
32+
| :? uint64 as v -> bigint v |> Some
33+
| :? float32 as v -> bigint v |> Some
34+
| _ -> None
35+
36+
let isNumeric (value: ValueType) =
37+
isInteger value || isFloat value
38+
39+
let compare (value1: ValueType) (value2: ValueType) =
40+
if isNumeric value1 |> not then
41+
invalidArg "value1" "value1 is not a number."
42+
elif isNumeric value2 |> not then
43+
invalidArg "value2" "value2 is not a number."
44+
45+
// Use BigInteger as common integral type
46+
match tryToBigInt value1, tryToBigInt value2 with
47+
| Some bigint1, Some bigint2 ->
48+
BigInteger.Compare(bigint1, bigint2) |> enum<NumericRelationship>
49+
50+
// At least one value is floating point use Double.
51+
| _ ->
52+
let dbl1 =
53+
try
54+
Convert.ToDouble value1
55+
with
56+
| :? OverflowException ->
57+
printfn "value1 is outside the range of a Double."
58+
0.
59+
| _ -> 0.
60+
61+
let dbl2 =
62+
try
63+
Convert.ToDouble value2
64+
with
65+
| :? OverflowException ->
66+
printfn "value2 is outside the range of a Double."
67+
0.
68+
| _ -> 0.
69+
70+
dbl1.CompareTo dbl2 |> enum<NumericRelationship>
71+
// </Snippet1>
72+
73+
// <Snippet2>
74+
printfn $"{Utility.isNumeric 12}"
75+
printfn $"{Utility.isNumeric true}"
76+
printfn $"{Utility.isNumeric 'c'}"
77+
printfn $"{Utility.isNumeric (DateTime(2012, 1, 1))}"
78+
printfn $"{Utility.isInteger 12.2}"
79+
printfn $"{Utility.isInteger 123456789}"
80+
printfn $"{Utility.isFloat true}"
81+
printfn $"{Utility.isFloat 12.2}"
82+
printfn $"{Utility.isFloat 12}"
83+
printfn $"{12.1} {Utility.compare 12.1 12} {12}"
84+
// The example displays the following output:
85+
// True
86+
// False
87+
// False
88+
// False
89+
// False
90+
// True
91+
// False
92+
// True
93+
// False
94+
// 12.1 GreaterThan 12
95+
// </Snippet2>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="example1.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// <Snippet1>
2+
namespace Corporate.EmployeeObjects
3+
4+
[<Struct>]
5+
type EmployeeA =
6+
val mutable Name : string
7+
8+
[<Struct>]
9+
type EmployeeB =
10+
val mutable Name : string
11+
override this.ToString() =
12+
this.Name
13+
14+
module Example =
15+
let empA = EmployeeA(Name="Robert")
16+
printfn $"{empA}"
17+
18+
let empB = EmployeeB(Name="Robert")
19+
printfn $"{empB}"
20+
// The example displays the following output:
21+
// Corporate.EmployeeObjects.EmployeeA
22+
// Robert
23+
// </Snippet1>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="ToString2.fs" />
9+
</ItemGroup>
10+
</Project>

xml/System/ValueType.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@
6666
Aside from serving as the base class for value types in the .NET Framework, the <xref:System.ValueType> 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 <xref:System.ValueType> 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 <xref:System.ValueType>, and reference types are prevented from being passed to the methods.
6767
6868
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Overview/example1.cs" id="Snippet1":::
69+
:::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Overview/example1.fs" id="Snippet1":::
6970
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.valuetype.structure/vb/example1.vb" id="Snippet1":::
7071
7172
The following example illustrates calls to the methods of the `Utility` class.
7273
7374
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Overview/example1.cs" id="Snippet2":::
75+
:::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Overview/example1.fs" id="Snippet2":::
7476
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.valuetype.structure/vb/example1.vb" id="Snippet2":::
7577
7678
]]></format>
@@ -196,6 +198,7 @@
196198
197199
:::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR/ValueType.Equals Example/CPP/source.cpp" id="Snippet1":::
198200
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Equals/source.cs" id="Snippet1":::
201+
:::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Equals/source.fs" id="Snippet1":::
199202
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR/ValueType.Equals Example/VB/source.vb" id="Snippet1":::
200203
201204
]]></format>
@@ -266,6 +269,7 @@
266269
267270
:::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR/ValueType.Equals Example/CPP/source.cpp" id="Snippet1":::
268271
:::code language="csharp" source="~/snippets/csharp/System/ValueType/Equals/source.cs" id="Snippet1":::
272+
:::code language="fsharp" source="~/snippets/fsharp/System/ValueType/Equals/source.fs" id="Snippet1":::
269273
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR/ValueType.Equals Example/VB/source.vb" id="Snippet1":::
270274
271275
]]></format>
@@ -322,6 +326,7 @@
322326
Value types defined by the `struct` keyword in C# and the `Structure`...`End Structure` construct in Visual Basic typically override the <xref:System.ValueType.ToString%2A?displayProperty=nameWithType> 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 <xref:System.ValueType.ToString%2A?displayProperty=nameWithType> method, it displays only the fully qualified type name. The `EmployeeB.ToString` method, on the other hand, provides meaningful information about the object.
323327
324328
:::code language="csharp" source="~/snippets/csharp/System/ValueType/ToString/ToString2.cs" interactive="try-dotnet" id="Snippet1":::
329+
:::code language="fsharp" source="~/snippets/fsharp/System/ValueType/ToString/ToString2.fs" id="Snippet1":::
325330
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/System.ValueType.ToString/vb/ToString2.vb" id="Snippet1":::
326331
327332
Note that, although enumeration types are also value types, they derive from the <xref:System.Enum> class, which overrides <xref:System.ValueType.ToString%2A?displayProperty=nameWithType>.

0 commit comments

Comments
 (0)