F# class hierarchy comparison
What is the best way to tackle this problem? Here is a simple class hierarchy in F#:
[<AbstractClass>]
type BaseClass (name: string) =
member this开发者_运维百科.Name with get() = name
type FooClass (n, i: int) =
inherit BaseClass (n)
member this.Num with get() = i
type BarClass (n) = inherit BaseClass (n)
I will need to add to this hierarchy quite a lot as the project advances.
I need to equate instances of these classes by checking if they are the same type and have the same value for Name
(and also the same value for Num
if its a FooClass
), so ReferenceEquals won't cut it. What is the best way to do this? Should I make BaseClass
inherit IComparable and if so, how should I then deal with the types that inherit from BaseClass
and have extra fields to check? Another way of doing it would be to make an IComparer class that checks for every different class but I really want the code to be in the appropriate class rather than in a comparer
I believe overriding equals on the base class, and then overriding equals on each sub class by leveraging the base class implementation is the standard approach in .NET OO:
[<AbstractClass>]
type BaseClass (name: string) =
member this.Name with get() = name
override this.Equals(other:obj) =
match other with
| :? BaseClass as other ->
other.Name = this.Name
| _ -> false
type FooClass (n, i: int) =
inherit BaseClass (n)
member this.Num with get() = i
override this.Equals(other:obj) =
match other with
| :? FooClass as other when base.Equals(other) -> //check type equality with this, and base equality
other.Num = this.Num //check the additional properties for this supertype
| _ -> false
type BarClass (n, i: bool) =
inherit BaseClass (n)
member this.Truth with get() = i
override this.Equals(other:obj) =
match other with
| :? BarClass as other when base.Equals(other) ->
other.Truth = this.Truth
| _ -> false
let f1 = FooClass("Foo", 1)
let f2 = FooClass("Foo", 1)
f1 = f2 //true
let f3 = FooClass("Foo", 2)
f1 = f3 //false
//polymorphism in action (bc1 BaseClass will use sub class override)
let checkBaseClassesForEquality (bc1:BaseClass) (bc2:BaseClass) =
bc1 = bc2
checkBaseClassesForEquality f1 f2 //true
checkBaseClassesForEquality f1 f3 //false
精彩评论