Skip to content

Commit 45bf39b

Browse files
authored
Object F# snippets (#7811)
1 parent 072faf6 commit 45bf39b

40 files changed

+1188
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module equals2
2+
3+
// <Snippet1>
4+
type Point(x, y) =
5+
new () = Point(0, 0)
6+
member _.X = x
7+
member _.Y = y
8+
9+
override _.Equals(obj) =
10+
//Check for null and compare run-time types.
11+
match obj with
12+
| :? Point as p ->
13+
x = p.X && y = p.Y
14+
| _ ->
15+
false
16+
17+
override _.GetHashCode() =
18+
(x <<< 2) ^^^ y
19+
20+
override _.ToString() =
21+
$"Point({x}, {y})"
22+
23+
type Point3D(x, y, z) =
24+
inherit Point(x, y)
25+
member _.Z = z
26+
27+
override _.Equals(obj) =
28+
match obj with
29+
| :? Point3D as pt3 ->
30+
base.Equals(pt3 :> Point) && z = pt3.Z
31+
| _ ->
32+
false
33+
34+
override _.GetHashCode() =
35+
(base.GetHashCode() <<< 2) ^^^ z
36+
37+
override _.ToString() =
38+
$"Point({x}, {y}, {z})"
39+
40+
let point2D = Point(5, 5)
41+
let point3Da = Point3D(5, 5, 2)
42+
let point3Db = Point3D(5, 5, 2)
43+
let point3Dc = Point3D(5, 5, -1)
44+
45+
printfn $"{point2D} = {point3Da}: {point2D.Equals point3Da}"
46+
printfn $"{point2D} = {point3Db}: {point2D.Equals point3Db}"
47+
printfn $"{point3Da} = {point3Db}: {point3Da.Equals point3Db}"
48+
printfn $"{point3Da} = {point3Dc}: {point3Da.Equals point3Dc}"
49+
// The example displays the following output:
50+
// Point(5, 5) = Point(5, 5, 2): False
51+
// Point(5, 5) = Point(5, 5, 2): False
52+
// Point(5, 5, 2) = Point(5, 5, 2): True
53+
// Point(5, 5, 2) = Point(5, 5, -1): False
54+
// </Snippet1>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module equals3
2+
3+
// <Snippet1>
4+
type Point(x, y) =
5+
member _.X = x
6+
member _.Y = y
7+
8+
override _.Equals(obj) =
9+
// Performs an equality check on two points (integer pairs).
10+
match obj with
11+
| :? Point as p ->
12+
x = p.X && y = p.Y
13+
| _ ->
14+
false
15+
16+
override _.GetHashCode() =
17+
(x, y).GetHashCode()
18+
19+
type Rectangle(upLeftX, upLeftY, downRightX, downRightY) =
20+
let a = Point(upLeftX, upLeftY)
21+
let b = Point(downRightX, downRightY)
22+
23+
member _.UpLeft = a
24+
member _.DownRight = b
25+
26+
override _.Equals(obj) =
27+
// Perform an equality check on two rectangles (Point object pairs).
28+
match obj with
29+
| :? Rectangle as r ->
30+
a.Equals(r.UpLeft) && b.Equals(r.DownRight)
31+
| _ ->
32+
false
33+
34+
override _.GetHashCode() =
35+
(a, b).GetHashCode()
36+
37+
override _.ToString() =
38+
$"Rectangle({a.X}, {a.Y}, {b.X}, {b.Y})"
39+
40+
let r1 = Rectangle(0, 0, 100, 200)
41+
let r2 = Rectangle(0, 0, 100, 200)
42+
let r3 = Rectangle(0, 0, 150, 200)
43+
44+
printfn $"{r1} = {r2}: {r1.Equals r2}"
45+
printfn $"{r1} = {r3}: {r1.Equals r3}"
46+
printfn $"{r2} = {r3}: {r2.Equals r3}"
47+
// The example displays the following output:
48+
// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 100, 200): True
49+
// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
50+
// Rectangle(0, 0, 100, 200) = Rectangle(0, 0, 150, 200): False
51+
// </Snippet1>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module equals4
2+
3+
// <Snippet1>
4+
[<Struct; CustomEquality; NoComparison>]
5+
type Complex =
6+
val mutable re: double
7+
val mutable im: double
8+
9+
override this.Equals(obj) =
10+
match obj with
11+
| :? Complex as c when c = this -> true
12+
| _ -> false
13+
14+
override this.GetHashCode() =
15+
(this.re, this.im).GetHashCode()
16+
17+
override this.ToString() =
18+
$"({this.re}, {this.im})"
19+
20+
static member op_Equality (x: Complex, y: Complex) =
21+
x.re = y.re && x.im = y.im
22+
23+
static member op_Inequality (x: Complex, y: Complex) =
24+
x = y |> not
25+
26+
let mutable cmplx1 = Complex()
27+
let mutable cmplx2 = Complex()
28+
29+
cmplx1.re <- 4.0
30+
cmplx1.im <- 1.0
31+
32+
cmplx2.re <- 2.0
33+
cmplx2.im <- 1.0
34+
35+
printfn $"{cmplx1} <> {cmplx2}: {cmplx1 <> cmplx2}"
36+
printfn $"{cmplx1} = {cmplx2}: {cmplx1.Equals cmplx2}"
37+
38+
cmplx2.re <- 4.0
39+
40+
printfn $"{cmplx1} = {cmplx2}: {cmplx1 = cmplx2}"
41+
printfn $"{cmplx1} = {cmplx2}: {cmplx1.Equals cmplx2}"
42+
43+
// The example displays the following output:
44+
// (4, 1) <> (2, 1): True
45+
// (4, 1) = (2, 1): False
46+
// (4, 1) = (4, 1): True
47+
// (4, 1) = (4, 1): True
48+
// </Snippet1>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module equals_ref
2+
3+
// <Snippet2>
4+
// Define a reference type that does not override Equals.
5+
type Person(name) =
6+
override _.ToString() =
7+
name
8+
9+
let person1a = Person "John"
10+
let person1b = person1a
11+
let person2 = Person(string person1a)
12+
13+
printfn "Calling Equals:"
14+
printfn $"person1a and person1b: {person1a.Equals person1b}"
15+
printfn $"person1a and person2: {person1a.Equals person2}"
16+
17+
printfn "\nCasting to an Object and calling Equals:"
18+
printfn $"person1a and person1b: {(person1a :> obj).Equals(person1b :> obj)}"
19+
printfn $"person1a and person2: {(person1a :> obj).Equals(person2 :> obj)}"
20+
// The example displays the following output:
21+
// person1a and person1b: True
22+
// person1a and person2: False
23+
//
24+
// Casting to an Object and calling Equals:
25+
// person1a and person1b: True
26+
// person1a and person2: False
27+
// </Snippet2>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module equals_static2
2+
3+
// <Snippet1>
4+
open System
5+
6+
// Class constructor
7+
type Dog(dogBreed) =
8+
// Public property.
9+
member _.Breed = dogBreed
10+
11+
override this.Equals(obj) =
12+
match obj with
13+
| :? Dog as dog when dog.Breed = this.Breed -> true
14+
| _ -> false
15+
16+
override _.GetHashCode() =
17+
dogBreed.GetHashCode()
18+
19+
override _.ToString() =
20+
dogBreed
21+
22+
let m1 = Dog "Alaskan Malamute"
23+
let m2 = Dog "Alaskan Malamute"
24+
let g1 = Dog "Great Pyrenees"
25+
let g2 = g1
26+
let d1 = Dog "Dalmation"
27+
let n1 = Unchecked.defaultof<Dog>
28+
let n2 = Unchecked.defaultof<Dog>
29+
30+
printfn $"null = null: {Object.Equals(n1, n2)}"
31+
printfn $"null Reference Equals null: {Object.ReferenceEquals(n1, n2)}\n"
32+
33+
printfn $"{g1} = {g2}: {Object.Equals(g1, g2)}"
34+
printfn $"{g1} Reference Equals {g2}: {Object.ReferenceEquals(g1, g2)}\n"
35+
36+
printfn $"{m1} = {m2}: {Object.Equals(m1, m2)}"
37+
printfn $"{m1} Reference Equals {m2}: {Object.ReferenceEquals(m1, m2)}\n"
38+
39+
printfn $"{m1} = {d1}: {Object.Equals(m1, d1)}"
40+
printfn $"{m1} Reference Equals {d1}: {Object.ReferenceEquals(m1, d1)}"
41+
42+
// The example displays the following output:
43+
// null = null: True
44+
// null Reference Equals null: True
45+
//
46+
// Great Pyrenees = Great Pyrenees: True
47+
// Great Pyrenees Reference Equals Great Pyrenees: True
48+
//
49+
// Alaskan Malamute = Alaskan Malamute: True
50+
// Alaskan Malamute Reference Equals Alaskan Malamute: False
51+
//
52+
// Alaskan Malamute = Dalmation: False
53+
// Alaskan Malamute Reference Equals Dalmation: False
54+
// </Snippet1>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module equals_val1
2+
3+
// <Snippet3>
4+
let value1 = 12uy
5+
let value2 = 12
6+
7+
let object1 = value1 :> obj
8+
let object2 = value2 :> obj
9+
10+
printfn $"{object1} ({object1.GetType().Name}) = {object2} ({object2.GetType().Name}): {object1.Equals object2}"
11+
12+
// The example displays the following output:
13+
// 12 (Byte) = 12 (Int32): False
14+
// </Snippet3>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module equals_val2
2+
3+
// <Snippet4>
4+
// Define a value type that does not override Equals.
5+
[<Struct>]
6+
type Person(personName: string) =
7+
override _.ToString() =
8+
personName
9+
10+
let person1 = Person "John"
11+
let person2 = Person "John"
12+
13+
printfn "Calling Equals:"
14+
printfn $"{person1.Equals person2}"
15+
16+
printfn $"\nCasting to an Object and calling Equals:"
17+
printfn $"{(person1 :> obj).Equals(person2 :> obj)}"
18+
// The example displays the following output:
19+
// Calling Equals:
20+
// True
21+
//
22+
// Casting to an Object and calling Equals:
23+
// True
24+
// </Snippet4>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module equalsoverride
2+
3+
// <Snippet6>
4+
open System
5+
6+
type Person(name, id) =
7+
member _.Name = name
8+
member _.Id = id
9+
10+
override _.Equals(obj) =
11+
match obj with
12+
| :? Person as personObj ->
13+
id.Equals personObj.Id
14+
| _ ->
15+
false
16+
17+
override _.GetHashCode() =
18+
id.GetHashCode()
19+
20+
let p1 = Person("John", "63412895")
21+
let p2 = Person("Jack", "63412895")
22+
printfn $"{p1.Equals p2}"
23+
printfn $"{Object.Equals(p1, p2)}"
24+
// The example displays the following output:
25+
// True
26+
// True
27+
// </Snippet6>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module equalssb1
2+
3+
// <Snippet5>
4+
open System
5+
open System.Text
6+
7+
let sb1 = StringBuilder "building a string..."
8+
let sb2 = StringBuilder "building a string..."
9+
10+
printfn $"sb1.Equals(sb2): {sb1.Equals sb2}"
11+
printfn $"((Object) sb1).Equals(sb2): {(sb1 :> obj).Equals sb2}"
12+
13+
printfn $"Object.Equals(sb1, sb2): {Object.Equals(sb1, sb2)}"
14+
15+
let sb3 = StringBuilder "building a string..."
16+
printfn $"\nsb3.Equals(sb2): {sb3.Equals sb2}"
17+
// The example displays the following output:
18+
// sb1.Equals(sb2): True
19+
// ((Object) sb1).Equals(sb2): False
20+
// Object.Equals(sb1, sb2): False
21+
//
22+
// sb3.Equals(sb2): False
23+
// </Snippet5>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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="equals_ref.fs" />
9+
<Compile Include="equals_val1.fs" />
10+
<Compile Include="equals_val2.fs" />
11+
<Compile Include="equalssb1.fs" />
12+
<Compile Include="equalsoverride.fs" />
13+
<Compile Include="equals2.fs" />
14+
<Compile Include="equals3.fs" />
15+
<Compile Include="equals4.fs" />
16+
<Compile Include="equals_static2.fs" />
17+
</ItemGroup>
18+
</Project>

0 commit comments

Comments
 (0)