Just be aware that this kind of equality test recreates a flaw in objc equality testing, and is very fragile and problematic in one of the ways that Swift was intended to fix.
It only works dependably if all types which conform to the protocol are value-types, and can give false positives if the two Drawable instances involved have types that are parent and subclass.
For example (in a playground in Xcode 7 beta 3):
protocol Place
{
var size: CGSize {get}
func isEqualToPlace(place: Place) -> Bool
}
extension Place where Self: Equatable
{
func isEqualToPlace(place: Place) -> Bool
{
guard let other = place as? Self else { return false }
return self == other
}
}
class EmptyLot: Equatable, Place
{
var size: CGSize = CGSize(width: 10, height: 10)
}
func == (lhs: EmptyLot, rhs: EmptyLot) -> Bool {return lhs.size == rhs.size}
class Minefield: EmptyLot
{
var hasMines: Bool = true
}
func == (lhs: Minefield, rhs: Minefield) -> Bool {return (lhs.size == rhs.size) && (lhs.hasMines == rhs.hasMines)}
let x = EmptyLot()
let y = Minefield()
x.isEqualToPlace(y) // true
y.isEqualToPlace(x) // false
There is nothing you can do to the subclass which would make this code work correctly, so if the base class and protocol are in a framework the only solution would be to not inherit the class and rewrite all of the functionality that was in the base class, assuming the developer was even aware that there was a problem.
If you want instances to only potentially be equal if they have the exact same type, you end up needing to do something like this.
extension Place
{
func isActuallyEqualToPlace(place: Place) -> Bool
{
return self.mightBeEqualToPlace(place) && place.mightBeEqualToPlace(self)
}
func mightBeEqualToPlace(place: Place) -> Bool
{
guard let other = place as? Self else { return false }
return self == other
}
}
x.isActuallyEqualToPlace(y) // true
y.isActuallyEqualToPlace(x) // true