2009-03-12 5 views
2

Ich habe mit F # herumgespielt und es ist Reflection, versuche ein Record-Objekt dynamisch aus F # zu erstellen, ich habe das meiste davon funktioniert (wie du unten siehst) aber eine Sache - der Datensatz, den ich durch Reflektion erstelle, hat den Typ "obj" anstatt den, den er sollte ("Person") und ich kann nicht in der Lage sein, ihn in irgendeiner Weise zu verbessern.Upcasting F # Aufnahme durch Reflexion erstellt

#light 

type Person = { 
    Name:string; 
    Age:int; 
} 

let example = {Name = "Fredrik"; Age = 23;} 
// example has type Person = {Name = "Fredrik"; Age = 23;} 

let creator = Reflection.FSharpValue.PrecomputeRecordConstructor(example.GetType(), 
       System.Reflection.BindingFlags.Public) 

let reflected = creator [| ("thr" :> obj); (23 :> obj) |] 
// here reflected will have the type obj = {Name = "thr"; Age = 23;} 

// Function that changes the name of a Person record 
let changeName (x:Person) (name:string) = 
    { x with Name = name } 

// Works with "example" which is has type "Person" 
changeName example "Johan" 

// But not with "reflected" since it has type "obj" 
changeName reflected "Jack" // Error "This expression has type obj but is here used with type Person. " 

// But casting reflected to Person doesn't work either 
(reflected :> Person) // Type constraint mismatch. The type obj is not compatible with 
         // type Person. The type 'obj' is not compatible with the type 'Person'. 
         // C:\Users\thr\Documents\Visual Studio 2008\Projects\ 
         // Reflection\Reflection\Script.fsx 34 2 Reflection 

Antwort

2

Versuchen Sie, den anderen Cast-Operator mit

So Change (wie Sie in der anderen Richtung diesmal Gießen sind) (reflektierte :> Person) "Jack"

+0

Was ist der Unterschied zwischen der:> und:?> Operator? –

+0

Die beste Erklärung ist wahrscheinlich hier: http://stuff.mit.edu/afs/athena/software/fsharp_v1.1.12/FSharp-1.1.12.3/manual/import-interop.html#Upcasts Aber die Grundlagen sind Wenn Sie von einer Klasse zu ihrem Elternteil gehen (dh irgendetwas zu obj), verwenden Sie:>. Aber wenn Sie den anderen Weg gehen, verwenden Sie:?> ... – Massif

+2

":>" ist eine Upcast, ein Objekt in einen übergeordneten Typ konvertieren - es ist immer sicher, und Upcasting-Fehler können vom Compiler abgefangen werden. ":?>" ist ein Downcast, konvertiert ein Objekt in einen Nachkommen-Typ - Downcasts sind niemals sicher, da Downcast-Fehler immer zu Laufzeit-Ausnahmen führen. – Juliet