我有obj
实际上是元组DateTime*int*decimal*decimal
,它是obj
,因为我使用
tuple
let tupleType = typeof<(DateTime*int*decimal*decimal)>
let ret = FSharpValue.MakeTuple(x, tupleType)
现在我想将ret
投回DateTime*int*decimal*decimal
,我做了,
ret :?> DateTime*int*decimal*decimal
我的问题是我可以使用tupleType
进行投射,而不是像上面的代码那样明确指定类型吗?
答案 0 :(得分:5)
简短的回答是否。
在编译时已经进行了转换和类型检查。它被称为静态类型,因为类型独立于运行时(动态)值。当代码没有运行时(即静态),这些类型已经可用。
在编译时,ret
的静态类型为obj
,而在运行时,它的类型为DateTime*int*decimal*decimal
。
然而,编译器除非你说出来,否则不知道这一点。
同样,tupleType
在编译时和运行时都具有类型Type
。但是,它的值是DateTime*int*decimal*decimal
。该信息仅在运行时提供。
如果您希望ret
具有类型DateTime*int*decimal*decimal
,您需要告诉编译器这是类型。在编译时,tupleType
不提供该信息。
如果你可以设计你的系统以便你不需要使用反射,你可以保持类型安全,所以如果可能的话,它可能会更好选项。
答案 1 :(得分:4)
你不能按照预期的方式去做,正如马克在his answer中解释的那样。但是,您可以使用type abbreviation:
open System
open Microsoft.FSharp.Reflection
type MyTuple = DateTime*int*decimal*decimal
let ret = FSharpValue.MakeTuple([|DateTime.Now;1;1.0M;1.0M|],typeof<MyTuple>)
let myTuple = ret :?> MyTuple
获取类型myTuple
的{{1}},其中后者在编译时携带有关元组成员的类型信息。