1

我想知道这个错误来自哪里。这是代码,在使用 fsahrpx DSL 的 TP 下面

更新:我找到了一个“解决方案”,即在外面进行演员表,每次演员表构造一个吸气剂。如果有人知道为什么会发生这种情况,或者有更好的解决方案,我会很高兴知道。(ProvidedTypes-0.2.fs 中的有限引用模式?)

编辑:我绝望的失败尝试并不那么有趣。例如,两个有趣的是 Test93 或 Test92。他们为什么会失败?

更新 添加了最诉讼案件 90,91,92,93

module Module =
   open System.Reflection
   open Samples.FSharp.ProvidedTypes
   open FSharpx.TypeProviders.DSL
   open Microsoft.FSharp.Core.CompilerServices

   type ReflectiveBuilder = static member Cast<'a> (args:obj) = args :?> 'a
      static member BuildTypedCast lType (args: obj) = 
            typeof<ReflectiveBuilder>
               .GetMethod("Cast")
               .MakeGenericMethod([|lType|])
               .Invoke(null, [|args|])

   let bbgReference ns =
       erasedType<obj> (Assembly.GetExecutingAssembly()) ns "Reference"
       |> staticParameter "file"
          (fun typeName (parameterValues:string) ->
               let otwo = 2.0 :> obj
               let dtwo = 2.0 
               let dotwo = otwo :?> float

               let dcast = ReflectiveBuilder.BuildTypedCast typeof<float>

               let getter = match otwo with
                              | :? double as d -> (fun args -> <@@ d @@>)
                              | :? string as d -> (fun args -> <@@ d @@>)

               erasedType<string> (Assembly.GetExecutingAssembly()) ns typeName
           |+!> (   provideProperty 
                       "test90"                             //KO
                       (typeof<obj>)                   
                       (fun args -> <@@  otwo  @@>)     
                 )
           |+!> (   provideProperty 
                       "test91"                             //KO
                       (otwo.GetType())                  
                       (fun args -> <@@  otwo  @@>)     
                 )
           |+!> (   provideProperty 
                       "test92"                             //KO
                       (otwo.GetType())                  
                       (fun args -> <@@  otwo  @@>)     
                 )
           |+!> (   provideProperty 
                       "test93"                              //NO
                       typeof<float>                   
                       (fun args -> <@@  otwo :?> float  @@>)     
                 )

               |+!> (   provideProperty 
                           "test"                             //OK
                           typeof<float>                   
                           (fun args -> <@@  dtwo  @@>)      
                     )
               |+!> (   provideProperty 
                           "test2"                              //NO
                           typeof<float>                   
                           (fun args -> <@@  dtwo :> obj @@>)     
                     )
               |+!> (   provideProperty 
                           "test3"                              //NO
                           typeof<float>                   
                           (fun args -> <@@  otwo  @@>)     
                     )
               |+!> (   provideProperty 
                           "test4"                              //NO
                           typeof<float>                   
                           (fun args -> <@@  otwo :?> float  @@>)     
                     )
               |+!> (   provideProperty 
                           "test5"                              //OK
                           typeof<float>                   
                           (fun args -> <@@  dotwo  @@>)     
                     )
               |+!> (   provideProperty 
                           "test6"                              //OK
                           typeof<float>                   
                           (fun args -> <@@  dotwo :> obj  @@>)     
                     )
               |+!> (   provideProperty 
                           "test7"                              //NO
                           typeof<float>                   
                           (fun args -> <@@  dcast otwo  @@>)     
                     )
               |+!> (   provideProperty 
                           "test8"                              //OK
                           typeof<float>                   
                           getter    
                     )
               |+!> (provideConstructor
                        []
                        (fun _ -> <@@ "I will be the internal representation" @@>)))


   [<TypeProvider>]
   type public CustomTypeProvider(cfg:TypeProviderConfig) as this =
      inherit TypeProviderForNamespaces()

      do this.AddNamespace("TEST", [bbgReference "TEST"])

   [<TypeProviderAssembly>]
   do()

测试

module Program =
   open System

   type t = TEST.Reference<"">
   let price = t().Test90
   let price = t().Test91
   let price = t().Test92
   let price = t().Test93
   let price = t().Test    //OK
   let price = t().Test2   //OK
   let price = t().Test3   //NO OK
   let price = t().Test4   //NO OK
   let price = t().Test5   //OK
   let price = t().Test6   //OK
   let price = t().Test7   //NO OK
   let price = t().Test8   //OK
4

2 回答 2

3

可以出现在 F# 类型提供程序的属性和方法的引用代码中的表达式非常有限 - 我在编写类型提供程序时遇到了同样的问题。我不认为目前有一个精确的规范,所以找出答案的唯一方法是查看源代码或进行实验。

原因是,将 F# 引用编译为 IL 尚未在任何地方完全实现,因此类型提供程序的代码生成器可能只是实现了足以使其工作的基本功能。

在编写提供程序时,我通常遵循一种模式,即所有“运行时”代码都放在一个模块中,而传递给方法或属性的引用代码只是调用这个运行时。这是可行的,因为引用只是一个方法调用。就像是:

module CultureRuntime =
  let getCulture (name:string) = 
    // The runtime can contain arbitrary complex F# code
    CultureInfo.GetCultureInfo(name)

向提供者添加属性时,引用仅调用CultureRuntime.getCulture

for culture in CultureInfo.GetCultures(CultureTypes.AllCultures) do
  let id = culture.Name
  ProvidedProperty
    ( culture.DisplayName, typeof<CultureInfo>, IsStatic = true,
      GetterCode = fun args -> <@@ CultureRuntime.getCulture id @@>)
  |> sampleTy.AddMember

编辑:我不太熟悉类型提供程序的代码生成在内部是如何工作的,但是您发现令人惊讶的情况几乎总是可以使用<@ otwo @>或类似otwo的,类型的东西在哪里System.Object

当类型提供者从引用生成代码时,它需要为表达式生成 IL 代码otwo。但是,这通常没有意义,因为如果otwo是 type System.Object,那么您不能生成重新创建对象的 IL(或以其他方式序列化对象)。

出于这个原因,F# 类型提供程序机制(可能)只允许可以轻松转换为 IL 的原始值(例如float您的<@ dtwo @>示例中的类型值)。

于 2012-04-15T14:05:33.280 回答
2

我们计划在接下来的几周内在示例 codeplex 站点上发布对提供类型 API 的更新/修复。这个问题也将得到解决。

于 2012-05-02T21:50:36.960 回答