2009-03-12 4 views
2

私はF#とそれのリフレクションについて悩んでいますが、F#内からレコードタイプオブジェクトを動的に作成しようとしています。私がリフレクションを通して作成したレコードには、 "obj"タイプ( "Person")の代わりにタイプがあり、どのような方法でもアップキャストできないようです。リフレクションによって作成されたUpcasting F#レコード

#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 

答えて

2

のでchangeNameを(あなたが他の方法にこの時間をキャストしているとして)他のキャスト演算子を使用してみてください(反映:?>人)、「ジャック」は

+0

は違い何ですか:>および:?>演算子? –

+0

おそらく最も良い説明はここにあります: http://stuff.mit.edu/afs/athena/software/fsharp_v1.1.12/FSharp-1.1.12.3/manual/import-interop.html#Upcasts あなたがクラスからその親(つまり、何かがobjに)行くなら、あなたは:>を使います。しかし、あなたが他の方法を使用している場合:?> ... – Massif

+2

":>"はアップキャストで、オブジェクトを親タイプに変換します。常に安全で、アップキャストエラーはコンパイラによって捕捉されます。 ":?>"はダウンキャストで、オブジェクトを子孫型に変換します。ダウンキャストエラーは常に実行時例外を発生させるため、ダウンキャストは安全ではありません。 – Juliet

関連する問題