2016-02-02 75 views
3

在我first attempt創建一個類型提供的一個例子,我有一個消息ProvidedTypeDefinition:F#如何創建一個提供的類型

// Message type 
      let mTy = ProvidedTypeDefinition(asm, ns, message.Key, Some(typeof<ValueType>), 
         HideObjectMethods = true, IsErased = false) 
      // Direct buffer 
      let bufferField = ProvidedField("_directBuffer", typeof<IDirectBuffer>) 
      mTy.AddMember bufferField 

      let mCtor1 = 
      ProvidedConstructor(
       [ProvidedParameter("buffer", typeof<IDirectBuffer>)], 
       InvokeCode = fun args -> 
       match args with 
       | [this;buffer] -> 
        Expr.FieldSet (this, bufferField, <@@ %%buffer:IDirectBuffer @@>) 
       | _ -> failwith "wrong ctor params" 
      ) 
      mTy.AddMember mCtor1 

然後,我需要一種方法來創建該類型的實例另一種提供的類型。我這樣做:

let mMethod = ProvidedMethod(message.Key, [ProvidedParameter("buffer", typeof<IDirectBuffer>)], mTy) 
      mMethod.InvokeCode <- (fun [this;buffer] -> 
       let c = mTy.GetConstructors().Last() 
       Expr.NewObject(c, [ buffer ]) 
     ) 

ILSpy示出了下面的C#代碼等價物的方法:

public Car Car(IDirectBuffer buffer) 
     { 
      return new Car(buffer); 
     } 

,它也示出了Car結構是存在於測試組件(該測試組件構建行除非我訪問Car法):

enter image description here

但是當我嘗試創建

type CarSchema = SbeProvider<"Path\to\SBETypeProvider\SBETypeProvider\Car.xml"> 
module Test = 
    let carSchema = CarSchema() 
    let car = carSchema.Car(null) 

我收到以下錯誤:

  • 模塊/命名空間「SBETypeProvider」從編譯單元「tmp5CDE」不包含命名空間,模塊或類型「通過這樣的方法車車」

  • 到該類型的引用‘’在組件‘tmp5CDE’SBETypeProvider.Car被發現,但類型不能在組件中找到

我做錯了什麼?圖爲這裏的類型。爲什麼我無法創建它?

我查看了GitHub上的許多類型提供程序,找不到一個清晰的示例,說明如何從另一個生成ProvidedTypeDefinition

回答

2

這可能不是問題,但在快速瀏覽它看起來像line you linked實際上可能是問題:

let mTy = ProvidedTypeDefinition(asm, ns, message.Key, Some(typeof<ValueType>), 
         HideObjectMethods = true, IsErased = false) 

這種類型被添加到ty提供的類型(一個將實際被寫入臨時程序集),所以不應該有自己指定的程序集和名稱空間。

let mTy = ProvidedTypeDefinition(message.Key, Some(typeof<ValueType>), 
         HideObjectMethods = true, IsErased = false) 

可能會更好地工作。生成的類型雖然有一點黑色藝術,但是很少有文檔,所以有可能(很可能)會出現其他問題。

在更一般的說明中,對於創建提供的類型,我通常最終要做的是將提供的構造函數作爲值返回,然後可以使用Expr.Call將其嵌入到其他屬性/函數的調用代碼中。這對擦除類型尤其重要,因爲反射對它們無效。

+0

謝謝!那一年,這個錯誤超載的問題是幾個問題之一,也許是我的問題的主要問題之一!我已經向GitHub StarterPack提交了關於結構的另一個問題。你的名字+圖片告訴我,你是誰的主要貢獻者。 –

+0

我現在已經通過大多數已知的TP和F#大師的幫助,建立了更好的TPs心理模型。超載是主要問題,但仍然有如組裝解決這樣的「微妙之處」。爲什麼它仍然是「黑色藝術」,正如你所說!? TP是F#最受歡迎,最酷,最獨特和最強大的功能之一,但是當涉及到新的實現時,人們會迷失方向。他們完全迷失*完全*在一開始就像盲貓一樣:)如何改進文檔? –

相關問題