2015-10-22 19 views
5

Ho un gruppo di F # chiamato Assembly1Type.GetType() non funziona per F # di tipo in C# codice

Ho la seguente modulo:

namespace Assembly1 

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

In un'assemblea C# che fa riferimento a questo # assemblaggio F, il seguente codice mi restituisce il valore "null"

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

È ciò che sto cercando di non possibile?

risposta

5

Dato che hai inserito MyClass in un modulo, è stato compilato come classe nidificata. Il suo nome è Assembly1.MyModule+MyClass.

da C#, si dovrebbe essere in grado di caricare in questo modo:

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

Se non si desidera avere classi annidate (che sono generalmente malvista in C#), è possibile definire direttamente in uno spazio dei nomi:

namespace Assembly1.LibraryXyz 

type MyClass(x: int, y: int) = class end 

Questa classe avrà il nome Assembly1.LibraryXyz.MyClass.

+0

Grazie per la risposta. Funziona perfettamente! – bstack

6

Per aggiungere a Mark's answer, vale anche la pena notare che molti moduli in F # sono rappresentati da nomi diversi in IL (e quindi in lingue diverse da F #) rispetto a quelli visualizzati in F # stessa.

Ad esempio, questo pezzo di codice:

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") 

troverete il modulo Seq in FSharp.Core.

Lo spazio dei nomi FSharp.Reflection ha un sacco di metodi di supporto per rendere il lavoro con tipi specifici di F # con System.Reflection un po 'meno doloroso, quindi vale la pena caricare un paio di assiemi in FSI e giocare con quelli se farai molta riflessione con il codice F #.

È possibile creare moduli con nomi "non corrispondenti" come questo utilizzando l'attributo CompiledName - questo è particolarmente utile per le volte in cui si desidera un tipo e un modulo con lo stesso nome. La normale convenzione (come mostrato con il tipo/modulo Seq) è quella di annotare il modulo con il nome Compiled.

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