9.4.2.2 F# 中的向上转换和向下转换(UPCASTS AND DOWNCASTS)

728 篇文章 1 订阅
349 篇文章 0 订阅

9.4.2.2 F# 中的向上转换和向下转换(UPCASTSAND DOWNCASTS)

 

如果类型之间的转换不会失败,就称为向上转换(upcast)。我们已经看到,把类型转换成由该类型实现的接口,就是这种情况;另一个示例是把派生类转换成它的基类,在这种情况下,编译器也可以保证操作是正确的,不会失败。

如果有一个基本类型的值,希望将它转换为继承类,操作可能会失败,因为基类的值可能是目标类的值,也可能不是。在这种情况下,我们必须使用第二种类型转换,称为向下转换(downcast)。让我们用一个示例来说明,我们将使用标准的 Random 类,它是从 Object 类派生的(就像任何其他的 .NET 类一样):

 

> open System;; 

> let rnd = new Random();; 

val rnd : Random

 

> let rndObject = (rnd :>Object);;   <-- 成功,操作不会失败

val obj : Object

 

> let rnd2 = (rndObject :>Random);;                     |

stdin(4,12): error: Type constraintmismatch.              | 向上转换不正确

The type 'Object' is not compatible withthe type 'Random'  |

 

> let rnd2 = (rndObject :?>Random);;   <-- 成功,但可能会失败

val rnd2 : Random

 

> (rndObject :?> String);; 

System.InvalidCastException: Unable to castobject of type 

'System.Random' to type 'System.String'.

 

可以发现,如果我们偶然尝试不适当地使用了向上转换,F# 编译器报告这个错误。错误消息说,Object 与 Random 不兼容,这就是说,编译器不能保证 Object  类型的值能够转换到 Random 类型。最后,清单显示,向下转换可能失败,并且,如果试着将对象转换到错误的继承类,会抛出异常。

要想记住 F# 向上转换(>)和向下转换(:?>)的语法,有一个好办法,在使用向下转换时,有一些不确定因素,因为操作可能会失败。这种不确定性是向下转换运算符包含问号,而向上转换不包含的原因。F# 语言还提供了相当于 C# 中 is 的运算符,返回布尔值,说明对象实例是否可以转换为指定的类型。为了测试 obj 是否可以转换为 String,写成 obj :?> String。

在这里,思考一下 F# 和 C# 之间的差异,是值得的。在 C# 中,我们甚至不需要类型转换,如在清单 9.17 中:当编译器知道转换能成功,它不需要消歧,可以让它隐式发生。F# 不进行任何隐式转换,因此,用一个语言结构来表示转换,保证成功,是有道理的。在 C# 中还要使用,就没有什么意义了,所以很少使用,因为两种转换使用相同的语法,更简单。明确指定转换的编程风格,使得类型推断成为可能,而且,通常有助于阐明代码实际上在做什么。 

只用一章(合理的大小!)的篇幅,就想讲清所有F# 面向对象的特性,是不可能的,但我们已经知道要把函数式应用程序转变成实际的 .NET 代码,那些是最重要的。

我们已经多次说过,这些改变使 F# 代码更容易在 C# 中访问,因此,现在是证明的时候了,同时,要展示互操作是如何配合的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值