bst*_*ack 5 reflection f# c#-to-f#
我有一个名为Assembly1的F#程序集
我有以下模块:
namespace Assembly1
module MyModule =
type MyClass(x: int, y: int) =
new() = MyClass(0, 0)
Run Code Online (Sandbox Code Playgroud)
在引用此F#程序集的C#程序集中,以下代码为我提供了一个'null'值:
var myType = Type.GetType("Assembly1.MyModule.MyClass, Assembly1");
Run Code Online (Sandbox Code Playgroud)
我想做的不可能吗?
要添加Mark的答案,还值得注意的是,F#中的许多模块由IL(因此非F#语言)中的不同名称表示,而不是F#本身中显示的.
例如,这段代码:
open System
open System.Reflection
open Microsoft.FSharp.Reflection
let private core =
AppDomain.CurrentDomain.GetAssemblies()
|> Seq.find (fun a -> a.GetName().Name = "FSharp.Core")
let private seqMod =
core.GetTypes()
|> Seq.filter FSharpType.IsModule
|> Seq.find (fun t ->
t.FullName = "Microsoft.FSharp.Collections.SeqModule")
Run Code Online (Sandbox Code Playgroud)
将在FSharp.Core中找到Seq模块.
该FSharp.Reflection命名空间有一堆的辅助方法,以与F#特定类型的工作与的System.Reflection一点点痛苦少,所以它的价值装载量在FSI几个组件,并具有与那些一出戏,如果你打算使用F#代码进行大量的反射工作.
您可以使用CompiledName属性自己创建具有"不匹配"名称的模块- 这对于您希望类型和模块具有相同名称的时间尤其有用.常规约定(如Seq类型/模块所示)是使用Compiled name注释模块.
[<CompiledName("MyTypeModule")>]
module MyType =
let getString m =
match m with
| MyType s -> s
Run Code Online (Sandbox Code Playgroud)
由于您已经放入MyClass了一个模块,因此它被编译为嵌套类.它的名字是Assembly1.MyModule+MyClass.
从C#开始,您应该可以像这样加载它:
var myType = Type.GetType("Assembly1.MyModule+MyClass, Assembly1");
Run Code Online (Sandbox Code Playgroud)
如果您不想拥有嵌套类(在C#中通常不赞成),您可以直接在命名空间中定义它:
namespace Assembly1.LibraryXyz
type MyClass(x: int, y: int) = class end
Run Code Online (Sandbox Code Playgroud)
这个类将有名称Assembly1.LibraryXyz.MyClass.