F#upcasting TextBlock到UIElement

时间:2010-08-21 14:06:29

标签: .net f# uielement

有什么问题:

let (x:UIElement) = upcast new TextBlock()

错误是:此处需要“System.ComponentModel.ISupportInitialize”类型且不可用。您必须添加对程序集'System,Version = 4.0.0 ....'

的引用

TextBlock UIElement的子类型...

请注意,执行错误消息所说的内容确实可以解决问题,但为什么有必要做一些基本的转发?

2 个答案:

答案 0 :(得分:8)

作为 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需要查看类型(以便填充成员)。

答案 1 :(得分:-3)

来自documentation

“在许多面向对象语言中,向上转换是隐式的;在F#中,规则略有不同。当您将参数传递给对象类型的方法时,会自动应用向上转换。但是,对于模块中的let-bound函数,除非将参数类型声明为灵活类型,否则upcasting不是自动的。有关更多信息,请参阅Flexible Types(F#)。“

如果您使用以下语法:

let (x:#UIElement) = new TextBlock()

您的代码将使用灵活类型(由#表示)并且它将编译。但是,现在你会收到警告:

“此构造使代码的通用性低于其类型注释所指示的。通过在'c:\ path \ Program'或附近使用'#','_'或其他类型注释隐含的类型变量。 fs'被限制为'TextBlock'类型。“