type . gettype()在c#代码中对f#类型不起作用



我有一个名为Assembly1的f#程序集

我有以下模块:

namespace Assembly1
module MyModule =
   type MyClass(x: int, y: int) =
   new() = MyClass(0, 0)

在引用这个f#程序集的c#程序集中,下面的代码返回给我一个'null'值:

var myType = Type.GetType("Assembly1.MyModule.MyClass, Assembly1");

我想做的是不可能的吗?

为了补充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")

将在FSharp.Core中找到Seq模块。

FSharp。反射命名空间有一堆帮助方法,可以在System中处理f#特定的类型。反射稍微不那么痛苦,所以如果你要用f#代码做很多反射工作,那么在FSI中加载几个程序集并玩一玩是值得的。

你可以使用CompiledName属性自己创建像这样的"不匹配"名称的模块——这在你想要一个类型和一个模块具有相同名称的时候特别有用。正常的约定(如Seq类型/module所示)是用已编译的名称注释模块。

[<CompiledName("MyTypeModule")>]
module MyType =
    let getString m =
        match m with
        | MyType s -> s

由于您已经将MyClass放入模块中,因此它被编译为嵌套类。它的名字是Assembly1.MyModule+MyClass

在c#中,你应该能够像这样加载它:

var myType = Type.GetType("Assembly1.MyModule+MyClass, Assembly1");

如果你不想要嵌套类(这在c#中通常是不允许的),你可以直接在命名空间中定义它:

namespace Assembly1.LibraryXyz
type MyClass(x: int, y: int) = class end

这个类将命名为Assembly1.LibraryXyz.MyClass

相关内容

  • 没有找到相关文章

最新更新