简体   繁体   English

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

[英]f# cast obj to tuple type from FSharpValue.MakeTuple

I have an obj which is actually a tuple DateTime*int*decimal*decimal , it is an obj , because I create the tuple by using, 我有一个obj ,实际上是一个元组DateTime*int*decimal*decimal ,它是一个obj ,因为我通过使用创建tuple

let tupleType = typeof<(DateTime*int*decimal*decimal)>
let ret = FSharpValue.MakeTuple(x, tupleType)

Now I would like to cast ret backto DateTime*int*decimal*decimal , I did, 现在我想把ret转回DateTime*int*decimal*decimal ,我做了,

 ret :?> DateTime*int*decimal*decimal

My question is can I use tupleType to do the casting instead of specifying the type explicitly as in the above code? 我的问题是我可以使用tupleType进行转换而不是像上面的代码那样明确指定类型吗?

.

The short answer is no . 简短的回答是否定的

Casting and type checking happens already at compile-time. 在编译时已经进行了转换和类型检查。 It's called static typing because the types are independent of the run-time (dynamic) values. 它被称为静态类型,因为类型独立于运行时(动态)值。 The types are already available when the code isn't running (ie is static ). 代码未运行时(即静态 ),这些类型已经可用。

At compile-time, ret has the static type obj , while at run-time it has the type DateTime*int*decimal*decimal . 在编译时, ret具有静态类型obj ,而在运行时它具有DateTime*int*decimal*decimal

The compiler, however, doesn't know this unless you tell it. 但是,除非你告诉它,否则编译器不会知道这一点。

Likewise, tupleType has the type Type at both compile-time and run-time. 同样, tupleType在编译时和运行时都具有Type It's value , however, is DateTime*int*decimal*decimal . 但它的DateTime*int*decimal*decimal That information is only available at run-time. 该信息仅在运行时提供。

If you want ret to have the type DateTime*int*decimal*decimal , you'll need to tell the compiler that this is the type. 如果你想让ret具有类型DateTime*int*decimal*decimal ,你需要告诉编译器这是类型。 At compile-time, tupleType doesn't provide that information. 在编译时, tupleType不提供该信息。

If you can design your system so that you don't need to use Reflection, you can probably stay type-safe, so if that's at all possible, it'd probably be a better option. 如果您可以设计系统以便不需要使用Reflection,那么您可以保持类型安全,所以如果可能的话,它可能是更好的选择。

You cannot do it the way you expected, as Mark explained in his answer . 正如马克在答案中解释的那样,你不能按照预期的方式去做。 However, what you can do is using 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

getting myTuple of type MyTuple , where the latter carries type information about tuple consituents at compile time . 获取myTuple类型的MyTuple ,后者在编译时携带有关元组成员的类型信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM