使用序列在F#中向上转换

时间:2013-11-19 14:19:44

标签: f#

我正在尝试使用F#中的表达式(System.Linq.Expression类)。以下是我遇到的问题的一个简单示例:

let blah = seq {
    yield Expression.New(typedefof<'T>)
    yield Expression.Constant(1)
}

我希望blah成为seq<Expression>。然而,序列通过第一个产量推断其类型,即NewExpression。这将导致第二个yield导致编译失败,因为它是ConstantExpression。一个有效的解决方案是提高所有收益率:

let blah = seq<Expression> {
    yield Expression.New(typedefof<'T>) :> Expression
    //or
    yield upcast Expression.Constant(1)
}

但是这感觉很笨拙,不得不每次都要升级。我认为灵活类型可能也是一种可能的解决方案,但我也遇到了麻烦。 seq<#Expression>似乎不起作用。

有没有一种方法可以生成一系列表达式,而不必对它们中的每一个进行上传?

1 个答案:

答案 0 :(得分:7)

正如其他人已经提到的,F#通常不会自动在代码中插入向上转换,因此您需要添加类型注释和强制转换或upcast关键字 - 我认为评论已涵盖所有选项。

编译器进行向上转换时有两种情况 - 一种是将参数传递给函数,另一种是在创建数组或列表文字时。第二个实际上可以用来简化你的例子:

let blah<'T> : Expression list = 
  [ Expression.New(typedefof<'T>) 
    Expression.Constant(1) ]

此处,编译器会自动向Expression插入上传。我想您的实际用例更复杂 - 当您需要使用yield的序列表达式时,这将无效,因为您正在编写序列表达式而不是列表文字