2017-08-04 41 views
1

我試圖覆蓋對象表達式中的類的接口,但無法訪問該類的「this」引用我正在進行子類化。對象表達式的接口部分中的對象引用

例子:

type IFoo = 
    abstract member DoIt: unit -> unit 

type Foo() = 
    member x.SayHey() = printfn "Hey!" 
    member x.SayBye() = printfn "Bye!" 
    interface IFoo with 
     member x.DoIt() = x.SayHey() // x is 'Foo' 


let foo = 
    { 
    new Foo() with 
     // Dummy since F# won't allow object expression with no overrides/abstract implementations 
     override x.ToString() = base.ToString() 
    interface IFoo with 
     member x.DoIt() = x.SayBye() // Error: x is 'IFoo' 
    } 

獎金的問題:我能以某種方式擺脫僞覆蓋的?

+0

如果你實際上並不需要任何覆蓋,然後爲什麼要在對象表達式中創建對象?如果完全需要一個對象,也許它可以由接口成員按需創建。很難說出什麼是最好的,而不瞭解你想要達到的目標。 –

+0

@BentTranberg在我的實例中,Foo實現了多個接口(客戶端可能會上傳到這個接口),在某些情況下,我需要按需實例的Foo調整一個或多個接口。當然,我可以創建新的子類,但在某些情況下,對象表達式更方便。 – monoceres

+0

沒錯,但我有點不確定是否知道對象表達式不需要類實例化。你可以沒有類,只有一個或多個接口。 –

回答

2

你要投你的訪問中IFoo使

let foo = 
    { 
     new Foo() with 
      override x.ToString() = base.ToString() 
     interface IFoo with 
      member x.DoIt() = (x :?> Foo).SayBye() 
    } 
+0

':>'應該是':?>',因爲這是一個沮喪。在這種情況下,我們知道它永遠不會失敗,但F#編譯器無法知道這一點,所以您必須使用':?>'運算符。 – rmunn

+0

oops。字符有什麼區別;-)謝謝 – robkuz

+0

啊,當然。 Downcasts通常看起來很骯髒,但我想這很好。我想知道爲什麼F#將對象表達式視爲與常規子類不同的東西.. – monoceres

3

IFoo接口投下你xFoo類型:

let foo = 
{ 
    new Foo() with 
     // Dummy since F# won't allow object expression with no overrides/abstract implementations 
     override x.ToString() = base.ToString() 
    interface IFoo with 
     member x.DoIt() = (x :?> Foo).SayBye() // No type error 
} 
+0

似乎robkuz快了一點,謝謝你的回答! – monoceres