所以,我试图让这个简单的测试在F#控制台应用程序中运行:
open System.Reflection
open System.ComponentModel.Composition
open System.ComponentModel.Composition.Hosting
[<Export(typeof<int -> string>)>]
let toString(i: int) = i.ToString()
[<EntryPoint>]
let main argv =
use catalog = new AssemblyCatalog(Assembly.GetEntryAssembly())
use container = new CompositionContainer(catalog)
let myFunction = container.GetExportedValue<int -> string>()
let result = myFunction(5)
0
我希望MEF能够正确解析该功能,但事实并非如此。 相反,我得到了这个:
未处理的类型异常
中'System.ComponentModel.Composition.CompositionContractMismatchException'
发生在System.ComponentModel.Composition.dll其他信息:
Cannot cast the underlying exported value of type 'Program.toString (ContractName="Microsoft.FSharp.Core.FSharpFunc(System.Int32,System.String)")' to type 'Microsoft.FSharp.Core.FSharpFunc``2[System.Int32,System.String]'.
FSharpFunc(System.Int32, System.String)
和FSharpFunc``2[System.Int32, System.String]
之间的区别是什么?答案 0 :(得分:3)
编译器将顶级F#函数转换为方法,因此您的示例将编译为:
[Export(FSharpFunc<int,string>)]
public string toString(int i) { return i.ToString(); }
这可能导致错误。您可以强制编译器通过调用一些返回函数的操作来生成FSharpFunc
类型的属性getter - 即使是简单的身份函数也不会:
let makeFunc f = f
[<Export(typeof<int -> string>)>]
let toString = makeFunc <| fun (i:int) ->
i.ToString()
我没有对此进行测试,但我认为它可行。也就是说,在这种情况下使用简单的单方法接口可能更安全。