我有類似的問題。我也被限制爲僅使用標準庫並且沒有外部依賴性。同時我想利用已有的IEqualityComparer
和IComparer
接口的現有實現。
所以,我最終作出我自己的包裝結構,我現在可以使用F#的內置地圖和設置:
[<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
我用它來創建內置的包裝方式在收集和內部創建密鑰/項目包裝,以使用戶代碼更友好。所以我會有類似
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
剛剛重溫這個問題:這是一個可怕的想法。創建一個代表你想要的行爲的新類型。 – 2014-11-01 19:06:59