F#4.0引入了为提供的方法提供静态参数的能力(参见http://blogs.msdn.com/b/fsharpteam/archive/2014/11/12/announcing-a-preview-of-f-4-0-and-the-visual-f-tools-in-vs-2015.aspx)
我希望我提供的方法的返回类型取决于用户提供的静态参数。
我需要在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 ()
答案 0 :(得分:1)
如果确实需要在每次使用不同的静态参数时向命名空间添加新类型,那么我认为唯一的方法是将所需信息存储在缓存中并触发{{1}当您需要向命名空间添加新类型时,请事后重新填充缓存中的所有类型。