f#将obj转换为FSharpValue.MakeTuple中的元组类型

时间:2016-03-10 07:36:28

标签: types casting f#

我有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进行投射,而不是像上面的代码那样明确指定类型吗?

2 个答案:

答案 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}},其中后者在编译时携带有关元组成员的类型信息