2010-08-21 38 views
3

什麼是錯的:F#上溯造型的TextBlock到的UIElement

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

的錯誤是:類型 'System.ComponentModel.ISupportInitialize' 這裏需要和不可用。您必須添加一個引用到組裝「系統,版本= 4.0.0 ....」

TextBlockUIElement亞型......

注意,這樣做的錯誤消息指出什麼解決問題,但爲什麼有必要做一些像上傳一樣基本的事情?

+1

TextBlock繼承自實現ISupportInitialize的FrameworkElement,所以我猜繼承鏈中的所有類型都必須可用。 – 2010-08-21 15:05:33

+0

相關:http://stackoverflow.com/questions/738349/why-must-i-chain-reference-assemblies – 2010-08-21 15:08:37

回答

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 

在這種情況下,智能感知需要看的類型(以便它可以填充成員完成)。

+1

TextBlock本身不在System.dll中,而是*繼承System.dll中的接口*。 – 2010-08-21 15:20:10

+0

@Mauricio:這就是我的意思,但我的描述不是很清楚 - 我添加了一個沒有解釋,這是因爲界面。謝謝! – 2010-08-21 18:26:42

+0

謝謝。這就說得通了。 – Jules 2010-08-21 21:16:33

-3

documentation:。

「在許多面向對象的語言,向上轉型是隱式的;在F#中,規則略有不同,當您將參數傳遞給在對象類型的方法上溯造型自動應用然而,對於模塊中的let-bound函數,上傳不是自動的,除非參數類型被聲明爲靈活類型。有關更多信息,請參見Flexible Types(F#)。

如果你使用的語法如下:

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

您的代碼將使用靈活型(由#所示),它會編譯。然而,現在你會得到一個警告:

「這個構造會導致代碼的泛型低於它的類型註釋所指示的類型變量所暗示的使用'#','_'或其他類型註釋或者在'c:\ path \ Program.fs'附近被限制爲鍵入'TextBlock'。「

+0

這回答了「爲什麼upcast?」的問題。不是「爲什麼需要參考?」這是OP要求的。 – 2010-08-21 15:09:19