2014-04-27 42 views
7

Basit bir veri erişim sınıfı oluşturarak F # arabirimleriyle biraz oynuyorum.F # içerisindeki arabirimleri kullanmanın daha basit bir yolu var mı?

arabirimidir:

benim endişelendiğim biraz olduğum şey
type UserAccess() = 
    let db = dbSchema.GetDataContext() 
    interface IUserAccess with 
     member this.GetUsers cond = 
      let query = query { 
       for row in db.Users do 
       select row } 
      query |> Seq.where cond 

     member this.GetAllUsers() = 
      (this:>IUserAccess).GetUsers (fun _ -> true) 

Ben GetAllUsers arıyorum yoludur: sınıfta

type IUserAccess = 
    abstract member GetUsers : (dbSchema.ServiceTypes.Users -> bool) -> dbSchema.ServiceTypes.Users seq 
    abstract member GetAllUsers : unit -> dbSchema.ServiceTypes.Users seq 

, ben bu şekilde yöntemleri arıyorum işlev, özellikle (this:>IUserAccess) bölümüyle. Aynı arabirimde uygulanan yöntemleri çağırmanın en basit yolu nedir?

Basit ben GetUsers ve GetAllUsers hem arayüz uygulaması çağırarak sonra UserAccess() sınıfın içinde doğrudan GetUsers yöntemi oluşturma ve aklınıza gelebilecek seçenek, ama ben kaçınmak istiyorum uygulanan yeni bir özel yöntem anlamına gelir. Başka seçenek var mı?

cevap

6

F # her zaman belirtildiği şekilde seçenekleriniz oldukça fazla olan, açıkça arabirimleri uygulayan, ancak bağlayıcı bir let getirerek gereksiz dökümü önleyebilirsiniz: ben alabilir ben sadece basitleştirilmiş

type IUserAccess = 
    interface 
     abstract member GetUsers : (obj -> bool) -> unit 
     abstract member GetAllUsers : unit -> unit 
    end 

type Foo() as self = 
    let userAccess = self :> IUserAccess 
    interface IUserAccess with 
     member this.GetUsers(q : (obj -> bool)) : unit = 
      () 
     member this.GetAllUsers() = 
      userAccess.GetUsers(fun _ -> true) 

senin arayüzü ve nesne Gerçekten hızlı bir şekilde derleme.

+0

Teşekkürler, bu tam olarak aradığım basit iyileştirme! –

7

Sanırım sınıfın içinde ayrı bir yöntemi tanımlamaktan kaçınmak istiyorsanız, @vcsjones çözümünün muhtemelen en iyi seçenek olduğunu düşünüyorum. Yani, ayrı bir yöntemi açıklamak aslında çirkin değil. Sen (otomatik özel yöntem olarak derlenmiş olan) bağlama let kullanarak yerel tanımını kullanabilir ve bunu kod oldukça güzel görünmesini sağlar düşünüyorum:

type UserAccess() = 
    let db = dbSchema.GetDataContext() 
    let getUsers cond = 
     let query = query { 
      for row in db.Users do 
      select row } 
     query |> Seq.where cond 

    interface IUserAccess with 
     member this.GetUsers cond = getUsers cond 
     member this.GetAllUsers() = getUsers (fun _ -> true) 

Genellikle oldukça bu tarz gibi, tamamen özel uygulama ayırır çünkü kamuya açık API'yi tanımladığınız tanımın parçası.

İlgili konular