F# 如何向提供的方法提供带有静态参数的返回类型
F#4.0引入了为提供的方法提供静态参数的能力(请参阅) 我希望提供的方法的返回类型取决于用户提供的静态参数 我需要在DefineStaticParameters回调之外定义返回类型,以便将其传递给F# 如何向提供的方法提供带有静态参数的返回类型,f#,type-providers,F#,Type Providers,F#4.0引入了为提供的方法提供静态参数的能力(请参阅) 我希望提供的方法的返回类型取决于用户提供的静态参数 我需要在DefineStaticParameters回调之外定义返回类型,以便将其传递给this.AddNamespace,但不幸的是,这意味着AddMethod会被多次调用,我最终会遇到一堆不需要的重载。 如果我将returnType的创建移动到DefineStaticParameters回调中,则无法将其传递到AddNamespace,并且类型提供程序不再起作用 我如何解决这个难题
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中按返回类型的实例上的点时至少有一次),因此我仍然可能会生成大量不必要的类。添加缓存逻辑应该不会太难,这样您就不会不必要地创建重复的类型。