F#类重新排序Visual Studio

时间:2012-02-06 17:44:42

标签: 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

所以在上面的情况下,我得到错误“Album”没有定义。

有办法解决这个问题吗?或者我只需要重新考虑我的类型的整个层次结构?

1 个答案:

答案 0 :(得分: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