سؤال

أحاول استخدام عمليات تعيين مع فئة لدي. كل مثيل من هذه الفئة له معرف فريد. هل أحتاج إلى تطبيق نظام النظام.

type SomeClass(id : int) =
    member this.ID = id

let someSet = Set.of_list [SomeClass(1); SomeClass(2)]
let test = someSet.Contains(SomeClass(2))    
هل كانت مفيدة؟

المحلول

إليك تنفيذ يجب أن يعمل:

type SomeClass(id : int) =    
    member this.ID = id
    override this.Equals(o) =
        match o with
        | :? SomeClass as sc -> this.ID = sc.ID
        | _ -> false
    override this.GetHashCode() =
        id.GetHashCode()
    interface System.IComparable with
        member this.CompareTo(o) =
            match o with
            | :? SomeClass as sc -> compare this.ID sc.ID
            | _ -> -1

نصائح أخرى

أعتقد أنك سوف تحتاج إلى تنفيذ IComparer<T> لوضع الفهم (على سبيل المثال Set.of_list) للعمل. فيلا IComparable<T>, ، والتي تميل إلى أن تكون أقل استخداما على نطاق واسع - على الرغم من أنني قد أكون مخطئا.)

هذه مشاركة مدونة يشرح بشكل عام كيفية تنفيذ واجهات في F #. ويشمل أيضا مثالا محددا لنوع تنفيذ IComparer<T>, ، والذي في الواقع ليس واضحا تماما كما قد تأمل.

type Comp() =  
    interface IComparer with  
        member x.Compare(a, b) = 0  
    member x.Compare(a, b) = (x :> IComparer).Compare(a,b)  

اسمحوا لي أن أعرف إذا كان يعمل لك. لدي بعض الشكؤ أنك قد تحتاج في الواقع إلى تنفيذ IEqualityComparer<T> بدلا من ذلك، نظرا لأن هذا ما تستند إليه طرق ملحق LinQ في جميع أنحاء، بقدر ما أعرف. (حقا يحصل مربكة بكل هذه الواجهات للمقارنة في BCL!)

فيما يتعلق بالتعليق على إجابتي الأخرى، يمكنك عامل ذلك في فئة أساسية قابلة لإعادة الاستخدام، لكنني لست متأكدا من أنها فكرة جيدة حقا:

type EqCompBase<'EqKey, 
        'DerivedType when 'DerivedType :> EqCompBase<'EqKey,'DerivedType> >
        (id : 'EqKey) =    
    member this.ID = id
    override this.Equals(o) =
        match o with
        | :? EqCompBase<'EqKey, 'DerivedType> as sc -> this.ID = sc.ID
        | _ -> false
    override this.GetHashCode() =
        id.GetHashCode()
    interface System.IComparable with
        member this.CompareTo(o) =
            match o with
            | :? EqCompBase<'EqKey, 'DerivedType> as sc -> compare this.ID sc.ID
            | _ -> -1

type SomeClass(id : int, otherFieldThatDoesNotMatterForEquality : string) =
    inherit EqCompBase<int, SomeClass>(id)

let someSet = Set.of_list [SomeClass(1,"yadda"); SomeClass(2,"blah")]
let test = someSet.Contains(SomeClass(2,"foo"))
printfn "%A" test  // true
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top