出什么问题了:
let (x:UIElement) = upcast new TextBlock()
错误是:此处需要类型“System.ComponentModel.ISupportInitialize”且不可用。您必须添加对程序集“系统,版本 = 4.0.0 ....”的引用
TextBlock
是UIElement
...的一个亚型
请注意,按照错误消息所说的去做确实可以解决问题,但是为什么有必要做一些像向上转换这样基本的事情呢?
正如lasseespeholt在他的(现在已删除?)答案中提到的那样,您的代码没有任何问题,您只需要System.dll
按照错误消息的提示添加对的引用。
但这是怎么回事?
您在该特定行上收到错误消息,因为它是编译器从库中遇到某种类型的第一个地方System.dll
(接口ISupportInitialize
,由 实现TextBlock
)并意识到它需要对库的引用才能理解类型。
获得相同错误消息的另一种方法是这样写:
let x = new TextBlock()
x. // If you get IntelliSense here, you'll see just '<Note>'
// with the same error message as the one you're getting
在这种情况下,IntelliSense 需要查看类型(以便它可以填充成员完成)。
从文档中:
“在许多面向对象的语言中,向上转换是隐式的;在 F# 中,规则略有不同。当您将参数传递给对象类型的方法时,向上转换会自动应用。但是,对于模块中的 let 绑定函数,向上转换不是自动,除非参数类型被声明为灵活类型。有关更多信息,请参阅灵活类型(F#)。
如果您使用以下语法:
let (x:#UIElement) = new TextBlock()
您的代码将使用灵活的类型(由 表示#
)并且可以编译。但是,现在您会收到警告:
“这种结构导致代码的通用性低于其类型注释所指示的类型。在 'c:\path\Program.fs' 处或附近使用 '#'、'_' 或其他类型注释所暗示的类型变量具有被限制为“TextBlock”类型。”