2012-02-06 64 views
1

Im建立一個示例應用程序,其中我的類型層次結構不適用於在Visual Studio中進行類型排序。無論我如何嘗試安排文件(上,下),我都無法定義所有的類。F#類重新排序Visual Studio

所以他們的順序是F#中的項目

type Artist() = 
    let mutable artistId = 0 
    let mutable name = String.Empty 

    member x.ArtistId 
     with get() = artistId 
     and set (value) = artistId <- value 

    member x.Name 
     with get() = name 
     and set (value) = name <- value 

type Genre() = 
    let mutable name = String.Empty 
    let mutable genreId = 0 
    let mutable description = String.Empty 
    let mutable albums = [new Album()] 

    member x.Name 
     with get() = name 
     and set (value) = name <- value 

    member x.GenreId 
     with get() = genreId 
     and set (value) = genreId <- value 

    member x.Description 
     with get() = description 
     and set (value) = description <- value 

    member x.Albums 
     with get() = albums 
     and set (value) = albums <- value 

and Album() = 
    let mutable title = String.Empty 
    let mutable genre = new Genre() 
    let mutable albumId = 0 
    let mutable genreId = 0 
    let mutable artistId = 0 
    let mutable price : decimal = Decimal.Zero 
    let mutable albumArtUrl = String.Empty 
    let mutable artist = new Artist() 

    member x.Title 
     with get() = title 
     and set (value) = title <- value 

    member x.Genre 
     with get() = genre 
     and set (value) = genre <- value 

    member x.AlbumId 
     with get() = albumId 
     and set (value) = albumId <- value 

    member x.GenreId 
     with get() = genreId 
     and set (value) = genreId <- value 

    member x.ArtistId 
     with get() = artistId 
     and set (value) = artistId <- value 

    member x.Price 
     with get() = price 
     and set (value) = price <- value 

    member x.AlbumArtUrl 
     with get() = albumArtUrl 
     and set (value) = albumArtUrl <- value 

    member x.Artist 
     with get() = artist 
     and set (value) = artist <- value 

因此,在上述情況下,我得到的錯誤「專輯」沒有定義。

有沒有辦法解決這個問題?或者我只需要重新考慮我的類型的整個層次結構?

+0

所以基本上體裁類型包含列表,專輯和專輯類型包含類型的字段。是否有可能在F#中定義這種類型的層次? – netmatrix01 2012-02-06 17:53:13

+3

靠近舒適的計算機寫一個完整的答案,但總之 - 如果你把類型放在同一個模塊/命名空間中,你可以有相互遞歸類型。只要將它們依次放置,並用關鍵字「和」替換第二個「type」關鍵字。如果你去MSDN的關於F#類型的文章,它會有一個更完整的解釋。 – 2012-02-06 18:01:05

回答

5

如果您需要定義兩種類型,即相互遞歸(這意味着它們可以互相引用),那麼您需要將它們放在一個文件中並使用type ... and ...語法。

在你的榜樣,這意味着GenreAlbum需要被這樣定義:

// Start a definition block using 'type' as normal 
type Genre() = 
    let mutable name = String.Empty 
    let mutable albums = [new Album()] 

    member x.Name 
     with get() = name 
     and set (value) = name <- value 
    member x.Albums 
     with get() = albums 
     and set (value) = albums <- value 

// Continue single type definition block using 'and' 
and Album() = 
    let mutable genre = new Genre() 
    let mutable albumId = 0 
    let mutable artist = new Artist() 

    member x.Genre 
     with get() = genre 
     and set (value) = genre <- value  
    member x.AlbumId 
     with get() = albumId 
     and set (value) = albumId <- value  
    member x.Artist 
     with get() = artist 
     and set (value) = artist <- value 

但是,你的例子是使用在一個非常C#風格的F#,因此代碼看上去真的很優雅,它可能不會給你許多功能編程的好處。

如果我想表示您正在使用的結構,那麼我可能不會將該類型的引用添加到Album類型中。當您在Genre中放置相冊列表時,在處理數據結構時(即將其轉換爲其他結構,可能是F#記錄,可傳遞給數據綁定),您將始終能夠恢復流派, 。 F#的特點是它可以讓你在幾行上編寫域,但只適用於函數類型。

使用與單一情況下識別聯合,你可以寫:

// Type aliases to make code more readable 
type Name = string 
type AlbumID = int 

// Simple type definitions to represent the domain 
type Artist = Artist of Name 
type Album = Album of AlbumID * Artist 
type Genre = Genre of Name * Album list 
+0

很酷,正在考慮嘗試這一點,我想我已經在某個地方早些時候閱讀過,被遺忘了。非常感謝 – netmatrix01 2012-02-06 18:07:28

+0

但我認爲我們應該有一種更清晰的方式來將不同文件中的類型分開,因爲現在它起作用了,不能抱怨太多,只是在考慮大文件可能會變得棘手。 – netmatrix01 2012-02-06 18:10:11

+1

@ netmatrix01在一個更大的項目中,您將不得不使用接口。將'Genre'和'Album'定義爲接口(在一個文件中),然後可以在大量文件之間分開實際實現並引用這些接口。 – 2012-02-06 18:15:08

相關問題