si può abusare inline
e membri dei vincoli da fare anatra digitando, che ti porta alcuni dei benefici dei mixin. Ad esempio, si potrebbe tradurre questo codice Ruby (tratto da this tutorial):
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"
a questo:
type Phonograph(id, name) =
member x.Id : int = id
override x.ToString() = name
type EightTrack(id, name) =
member x.Id : int = id
override x.ToString() = name
module Debug =
let inline whoAmI x =
sprintf "%s (%d) : %s"
(^T : (member GetType : unit -> Type) x).Name
(^T : (member Id : int with get) x)
(^T : (member ToString : unit -> string) x)
let ph = Phonograph(537766170, "West End Blues")
let et = EightTrack(537765860, "Surrealistic Pillow")
Debug.whoAmI ph //"Phonograph (537766170) : West End Blues"
Debug.whoAmI et //"EightTrack (537765860) : Surrealistic Pillow"
Ha il vantaggio (discutibile) su metodi di estensione di non richiedere una classe base comune o interfaccia. Per quanto riguarda la tua precedente domanda relativa alla parola chiave open
, potresti avere diversi moduli che definiscono whoAmI
e l'ultimo open
ultimo ombreggia quelli precedenti. In questo modo puoi "mescolare" il modulo che desideri. La libreria di base F # utilizza un approccio simile con checked operators.
Abbastanza collegato: http://stackoverflow.com/q/1805473/162396 – Daniel