Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何向提供的方法提供带有静态参数的返回类型_F#_Type Providers - Fatal编程技术网

F# 如何向提供的方法提供带有静态参数的返回类型

F# 如何向提供的方法提供带有静态参数的返回类型,f#,type-providers,F#,Type Providers,F#4.0引入了为提供的方法提供静态参数的能力(请参阅) 我希望提供的方法的返回类型取决于用户提供的静态参数 我需要在DefineStaticParameters回调之外定义返回类型,以便将其传递给this.AddNamespace,但不幸的是,这意味着AddMethod会被多次调用,我最终会遇到一堆不需要的重载。 如果我将returnType的创建移动到DefineStaticParameters回调中,则无法将其传递到AddNamespace,并且类型提供程序不再起作用 我如何解决这个难题

F#4.0引入了为提供的方法提供静态参数的能力(请参阅)

我希望提供的方法的返回类型取决于用户提供的静态参数

我需要在DefineStaticParameters回调之外定义返回类型,以便将其传递给
this.AddNamespace
,但不幸的是,这意味着
AddMethod
会被多次调用,我最终会遇到一堆不需要的重载。 如果我将
returnType
的创建移动到
DefineStaticParameters
回调中,则无法将其传递到
AddNamespace
,并且类型提供程序不再起作用

我如何解决这个难题

示例代码:

[<TypeProvider>]
type MyTypeProvider (config : TypeProviderConfig) as this =
    inherit TypeProviderForNamespaces ()

    let ns = "Acme"
    let asm = Assembly.GetExecutingAssembly()

    let t = ProvidedTypeDefinition(asm, ns, "MyStaticClass", Some typeof<obj>, IsErased = true)    
    let returnType = ProviderImplementation.ProvidedTypes.ProvidedTypeDefinition(asm, ns, "MyReturnType", Some typeof<obj>, IsErased = true, HideObjectMethods = true)

    let myStaticMethod =
      let m = ProvidedMethod("SomeStaticMethod", [], typeof<obj>, IsStaticMethod = true)

      m.DefineStaticParameters(staticParams, fun nm args ->

        let providedMethod = ... // Generate a method for the return type depending on the args
        returnType.AddMember(providedMethod) // PROBLEM: This gets called multiple times and adds unwanted overloads to my returnType

        let m2 =
          let myParam = ProvidedParameter("foo", typeof<int>)
          ProvidedMethod(nm, [myParam], returnType, IsStaticMethod = true)

        m2.InvokeCode <- fun args3 ->
          <@@
            // invoke code goes here
          @@>

        t.AddMember(m2)
        m2
        )
      m

    do
      t.AddMember(myStaticMethod)
      this.AddNamespace(ns, [t;returnType])

[<assembly:TypeProviderAssembly>]
do ()
[]
键入MyTypeProvider(配置:TypeProviderConfig),如下所示=
继承TypeProviderForNamespaces()
让ns=“Acme”
设asm=Assembly.getExecutionGassembly()
设t=ProvidedTypeDefinition(asm,ns,“MyStaticClass”,某些类型的,iSeries=true)
让returnType=ProviderImplementation.ProvidedTypes.ProvidedTypeDefinition(asm,ns,“MyReturnType”,某些类型的,iSeries=true,HideObjectMethods=true)
让我们用myStaticMethod=
设m=ProvidedMethod(“SomeStaticMethod”,[],typeof,IsStaticMethod=true)
m、 DefineStaticParameters(staticParams,参数->
让providedMethod=…//根据参数为返回类型生成一个方法
returnType.AddMember(providedMethod)//问题:这会被多次调用,并将不需要的重载添加到我的returnType中
让m2=
设myParam=ProvidedParameter(“foo”,typeof)
提供的方法(nm,[myParam],返回类型,IsStaticMethod=true)
m2.1代码
t、 新增成员(m2)
平方米
)
M
做
t、 AddMember(myStaticMethod)
this.AddNamespace(ns[t;returnType])
[]
do()

如果每次使用不同的静态参数时确实需要向命名空间添加新类型,那么我认为唯一的方法是将所需信息存储在缓存中,并在需要向命名空间添加新类型时触发
Invalidate
事件,之后从缓存中重新填充所有类型。

这似乎是一个非常糟糕的API设计。我想知道是否可以修改providedtypes.fs,使DefineStaticParameters返回ProvidedTypeInfo[]而不是unit,或者更好的方法是将一个continuation作为参数。问题不在于providedtypes.fs,而在于低级类型提供程序API本身,其中
iprovidednespace
GetTypes
方法返回一个
Type[]
,并且不提供任何添加其他类型的方法。但是,也许您可以使用单个类型,然后将生成的每个单独类型作为成员嵌套在该容器类型中,而不是试图使它们直接作为命名空间的子级…问题是DefineStaticParameters回调经常被触发(当您第一次加载使用类型提供程序的项目时有几次,然后每次在visual studio中按返回类型的实例上的点时至少有一次),因此我仍然可能会生成大量不必要的类。添加缓存逻辑应该不会太难,这样您就不会不必要地创建重复的类型。