Type.GetType() 不适用于 C# 代码中的 F# 类型
Type.GetType() not working for F# type in C# code
我有一个名为 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");
我想做的是不可能的吗?
由于您已将 MyClass
放入模块中,因此它被编译为嵌套的 class。它的名字是 Assembly1.MyModule+MyClass
.
在 C# 中,您应该能够像这样加载它:
var myType = Type.GetType("Assembly1.MyModule+MyClass, Assembly1");
如果您不想嵌套 classes(这在 C# 中通常不受欢迎),您可以直接在命名空间中定义它:
namespace Assembly1.LibraryXyz
type MyClass(x: int, y: int) = class end
这个 class 的名称将是 Assembly1.LibraryXyz.MyClass
。
要补充 ,还值得注意的是,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.Reflection 命名空间有一堆辅助方法,可以让 System.Reflection 使用 F# 特定类型的工作稍微轻松一些,因此值得在 FSI 中加载几个程序集并拥有如果您要使用 F# 代码进行大量反思工作,可以尝试一下。
您可以使用 CompiledName 属性自己创建具有 "mismatching" 名称的模块 - 这对于您需要同名类型和模块的情况特别有用。通常的约定(如 Seq type/module 所示)是用编译名称注释模块。
[<CompiledName("MyTypeModule")>]
module MyType =
let getString m =
match m with
| MyType s -> s
我有一个名为 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");
我想做的是不可能的吗?
由于您已将 MyClass
放入模块中,因此它被编译为嵌套的 class。它的名字是 Assembly1.MyModule+MyClass
.
在 C# 中,您应该能够像这样加载它:
var myType = Type.GetType("Assembly1.MyModule+MyClass, Assembly1");
如果您不想嵌套 classes(这在 C# 中通常不受欢迎),您可以直接在命名空间中定义它:
namespace Assembly1.LibraryXyz
type MyClass(x: int, y: int) = class end
这个 class 的名称将是 Assembly1.LibraryXyz.MyClass
。
要补充
比如这段代码:
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.Reflection 命名空间有一堆辅助方法,可以让 System.Reflection 使用 F# 特定类型的工作稍微轻松一些,因此值得在 FSI 中加载几个程序集并拥有如果您要使用 F# 代码进行大量反思工作,可以尝试一下。
您可以使用 CompiledName 属性自己创建具有 "mismatching" 名称的模块 - 这对于您需要同名类型和模块的情况特别有用。通常的约定(如 Seq type/module 所示)是用编译名称注释模块。
[<CompiledName("MyTypeModule")>]
module MyType =
let getString m =
match m with
| MyType s -> s