Thanks to visit codestin.com
Credit goes to github.com

Skip to content

System.IEquatable<T> F# snippets #7767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions snippets/fsharp/System/IEquatableT/Equals/EqualsEx2.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
module EqualsEx2

// <Snippet3>
open System
open System.Text.RegularExpressions

type Person(lastName, ssn) =
let mutable lastName = lastName
let ssn =
if Regex.IsMatch(ssn, @"\d{9}") then
$"{ssn.Substring(0, 3)}-{ssn.Substring(3, 2)}-{ssn.Substring(5, 4)}"
elif Regex.IsMatch(ssn, @"\d{3}-\d{2}-\d{4}") then
ssn
else
raise (FormatException "The social security number has an invalid format.")

member _.SSN =
ssn

member _.LastName
with get () = lastName
and set (value) =
if String.IsNullOrEmpty value then
invalidArg (nameof value) "The last name cannot be null or empty."
else
lastName <- value

static member op_Equality (person1: Person, person2: Person) =
if box person1 |> isNull || box person2 |> isNull then
Object.Equals(person1, person2)
else
person1.Equals person2

static member op_Inequality (person1: Person, person2: Person) =
if box person1 |> isNull || box person2 |> isNull then
Object.Equals(person1, person2) |> not
else
person1.Equals person2 |> not

override _.GetHashCode() =
ssn.GetHashCode()

override this.Equals(obj: obj) =
match obj with
| :? Person as personObj ->
(this :> IEquatable<_>).Equals personObj
| _ -> false

interface IEquatable<Person> with
member this.Equals(other: Person) =
match box other with
| null -> false
| _ ->
this.SSN = other.SSN
// </Snippet3>
// Create a Person object for each job applicant.
let applicant1 = Person("Jones", "099-29-4999")
let applicant2 = Person("Jones", "199-29-3999")
let applicant3 = Person("Jones", "299-49-6999")

// Add applicants to a List object.
let applicants = ResizeArray()
applicants.Add applicant1
applicants.Add applicant2
applicants.Add applicant3

// Create a Person object for the final candidate.
let candidate = Person("Jones", "199-29-3999")
if applicants.Contains candidate then
printfn $"Found {candidate.LastName} (SSN {candidate.SSN})."
else
printfn $"Applicant {candidate.SSN} not found."

// Call the shared inherited Equals(Object, Object) method.
// It will in turn call the IEquatable<T>.Equals implementation.
printfn $"{applicant2.LastName}({applicant2.SSN}) already on file: {Person.Equals(applicant2, candidate)}."

// The example displays the following output:
// Found Jones (SSN 199-29-3999).
// Jones(199-29-3999) already on file: True.

// This tests the handling of null values, but does not appear in the documentation.
//
//public class Example
//{
// public static void Main()
// {
// var p1 = new Person("Joe", "613-24-0068")
// Person p2 = null
//
// Console.WriteLine(p1 == p2)
// }
//}
80 changes: 80 additions & 0 deletions snippets/fsharp/System/IEquatableT/Equals/Snippet12.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
open System
open System.Collections.Generic
open System.Text.RegularExpressions

type Person(lastName, ssn) =
let mutable lastName = lastName
let ssn =
if Regex.IsMatch(ssn, @"\d{9}") then
$"{ssn.Substring(0, 3)}-{ssn.Substring(3, 2)}-{ssn.Substring(5, 4)}"
elif Regex.IsMatch(ssn, @"\d{3}-\d{2}-\d{4}") then
ssn
else
raise (FormatException "The social security number has an invalid format.")

member _.SSN =
ssn

member _.LastName
with get () = lastName
and set (value) =
if String.IsNullOrEmpty value then
invalidArg (nameof value) "The last name cannot be null or empty."
else
lastName <- value

static member op_Equality (person1: Person, person2: Person) =
if box person1 |> isNull || box person2 |> isNull then
Object.Equals(person1, person2)
else
person1.Equals person2

static member op_Inequality (person1: Person, person2: Person) =
if box person1 |> isNull || box person2 |> isNull then
Object.Equals(person1, person2) |> not
else
person1.Equals person2 |> not

override _.GetHashCode() =
ssn.GetHashCode()

override this.Equals(obj: obj) =
match obj with
| :? Person as personObj ->
(this :> IEquatable<_>).Equals personObj
| _ -> false

interface IEquatable<Person> with
member this.Equals(other: Person) =
match box other with
| null -> false
| _ ->
this.SSN = other.SSN

// <Snippet12>
// Create a Person object for each job applicant.
let applicant1 = Person("Jones", "099-29-4999")
let applicant2 = Person("Jones", "199-29-3999")
let applicant3 = Person("Jones", "299-49-6999")

// Add applicants to a List object.
let applicants = ResizeArray()
applicants.Add applicant1
applicants.Add applicant2
applicants.Add applicant3

// Create a Person object for the final candidate.
let candidate = Person("Jones", "199-29-3999")
if applicants.Contains candidate then
printfn $"Found {candidate.LastName} (SSN {candidate.SSN})."
else
printfn $"Applicant {candidate.SSN} not found."

// Call the shared inherited Equals(Object, Object) method.
// It will in turn call the IEquatable<T>.Equals implementation.
printfn $"{applicant2.LastName}({applicant2.SSN}) already on file: {Person.Equals(applicant2, candidate)}."

// The example displays the following output:
// Found Jones (SSN 199-29-3999).
// Jones(199-29-3999) already on file: True.
// </Snippet12>
11 changes: 11 additions & 0 deletions snippets/fsharp/System/IEquatableT/Equals/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="EqualsEx2.fs" />
<Compile Include="Snippet12.fs" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions xml/System/IEquatable`1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,13 @@
The following example shows the partial implementation of a `Person` class that implements <xref:System.IEquatable%601> and has two properties, `LastName` and `SSN`. The <xref:System.IEquatable%601.Equals%2A> method returns `True` if the `SSN` property of two `Person` objects is identical; otherwise, it returns `False`.

:::code language="csharp" source="~/snippets/csharp/System/IEquatableT/Equals/EqualsEx2.cs" id="Snippet3":::
:::code language="fsharp" source="~/snippets/fsharp/System/IEquatableT/Equals/EqualsEx2.fs" id="Snippet3":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.GenericIEquatable.Equals/vb/EqualsEx2.vb" id="Snippet3":::

`Person` objects can then be stored in a <xref:System.Collections.Generic.List%601> object and can be identified by the `Contains` method, as the following example shows.

:::code language="csharp" source="~/snippets/csharp/System/IEquatableT/Equals/Snippet12.cs" id="Snippet12":::
:::code language="fsharp" source="~/snippets/fsharp/System/IEquatableT/Equals/Snippet12.fs" id="Snippet12":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.GenericIEquatable.Equals/vb/Snippet12.vb" id="Snippet12":::

]]></format>
Expand Down