2017-02-03 8 views
4

私は「式を引用リテラルに連結するときに型の不一致があります」というエラーを与えるタイププロバイダを持っています。型プロバイダ内のinvokeの引用から関数を呼び出す方法はありますか?

小さなコンテキストで問題を再現するために、以下のコードを抽出しました。

let f (s : string) : string = s //some dummy implementation 

let t = ProvidedTypeDefinition(asm, ns, "Root", Some typeof<obj>) 
let ctor = ProvidedConstructor(parameters = [], 
           InvokeCode = (fun args -> <@@ "root" :> obj @@>)) :> MemberInfo 

let prop = ProvidedProperty(propertyName = "SomeProperty", 
          parameters = [], 
          propertyType = typeof<string>, 
          GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)) :> MemberInfo 

do t.AddMembers [ctor; prop] 
    t.SetBaseType typeof<obj> 

...と私は

let root = Provided.Root() 

let a = root.SomeProperty 

のようなタイプのプロバイダを使用するとき、私はエラーを取得する:

Error: The type provider 'typeproviders.providerpoc+MyProvider' reported an error in the context of provided type 'typeproviders.providerpoc.Provided.Root', member 'get_Menu'.

The error: Type mismatch when splicing expression into quotation literal.

The type of the expression tree being inserted doesn't match the type expected by the splicing operation.

Expected 'System.Object', but received type 'System.String'.

Consider type-annotating with the expected expression type, e.g., (%% x : string) or (%x : string).. Parameter name: receivedType.

私は二重引用符は関数を呼び出すことができるように書くことができますどのように引用の中に?

ありがとうございます!

+1

エラーメッセージに示されているように、予想されるタイプの注釈を付けてみましたか? –

+0

@FyodorSoikin - 'string'の部分が実際の型の不一致に関係しない例であり、_received_型ではなく_expected_型を表すため、メッセージは少し誤解を招きます。したがって、実際には '%%(args。[0]:obj)'を使う必要がありますが、 'f'は文字列を期待しているので、何も修正しません。 Tomasの答えはこれを修正する正しい方法を示しています。 – kvb

答えて

6

エラーメッセージは、タイプの引用された式が予想される場所に、タイプobjの引用符付き式を配置しているということです。

私は提供プロパティでGetterCodeを作成するときにこれが起こっている疑いがある:ここで

GetterCode = (fun args -> <@@ f %%(args.[0]) @@>) 

argsは、それぞれの式はタイプobjである引用された式の配列ですが、機能fは、文字列を期待し、そうタイプstring

トリックを行う必要がありobjstringに変わるであろう型変換を追加することべき%%を用いて穴を埋める引用:

GetterCode = (fun args -> <@@ f (unbox<string> (%%(args.[0]))) @@>) 
関連する問題