Tuve un problema similar. También estaba restringido para usar solo las bibliotecas estándar y sin dependencias externas. Al mismo tiempo, quería hacer uso de las implementaciones existentes de las interfaces IEqualityComparer
y IComparer
que ya tenía a mano.
Así, terminé de hacer mi propia estructura contenedora que ahora puedo usar con el F # 's integrado y conjunto:
[<Struct>]
[<CustomComparison>]
[<CustomEquality>]
type ComparisonAdapter<'T>(value: 'T, comparer: IComparer<'T>, eqComparer: IEqualityComparer<'T>) =
new(value) = ComparisonAdapter(value, Comparer<'T>.Default, EqualityComparer<'T>.Default)
member this.CompareTo (cmp: IComparer<'T>, v: 'T) = cmp.Compare(v, value)
member this.CompareTo (v: 'T) = this.CompareTo(comparer, v)
member this.CompareTo (c: ComparisonAdapter<'T>) = c.CompareTo(comparer, value)
member this.CompareTo (o: obj) =
if (o :? Comparison<'T>) then this.CompareTo(downcast o: ComparisonAdapter<'T>)
else if (o :? 'T) then this.CompareTo(downcast o: 'T)
else if (o :? IComparable) then ((downcast o: IComparable)).CompareTo(value)
else raise (NotSupportedException())
member this.Equals (c: ComparisonAdapter<'T>): bool = c.Equals(eqComparer, value)
member this.Equals (cmp: IEqualityComparer<'T>, v: 'T): bool = cmp.Equals(v, value)
member this.Equals (v: 'T): bool = eqComparer.Equals(v, value)
override this.Equals (o: obj): bool =
if (o :? Comparison<'T>) then this.Equals(downcast o: ComparisonAdapter<'T>)
else if (o :? 'T) then this.Equals(downcast o: 'T)
else false
override this.GetHashCode() = eqComparer.GetHashCode value
member this.Value with get() = value
interface IEquatable<'T> with member this.Equals other = this.Equals(eqComparer, other)
interface IComparable<'T> with member this.CompareTo other = this.CompareTo(comparer, other)
interface IComparable with member this.CompareTo o = this.CompareTo o
La forma en que lo uso es para crear un envoltorio de la incorporada en la recopilación y crea internamente el contenedor de clave/elemento para hacer que el código de usuario sea más amigable. Entonces tendría algo así como
type MyCustomMap<'TKey, 'TValue>(cmp: IComparer<'TKey>, eq: IEqualityComparer<'TKey>) =
let innerMap = new Map<ComparisonAdapter<'TKey>, 'TValue>()
member this Add key value =
let actualKey = new ComparisonAdapter<'TKey>(key, cmp, eq)
innerMap.Add actualKey value
Acabo de volver a esta pregunta: es una idea terrible. Crea un nuevo tipo que represente el comportamiento que deseas. –