我正在构建一个示例应用程序,其中我的类型层次结构不适用于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
Run Code Online (Sandbox Code Playgroud)
所以在上面的情况下,我得到错误"相册"没有定义.
有办法解决这个问题吗?或者我只需要重新考虑我的类型的整个层次结构?
如果您需要定义两个相互递归的类型(意味着它们可以互相引用),那么您需要将它们放在一个文件中并使用type ... and ...语法.
在你的榜样,这意味着Genre和Album需要被这样定义:
// 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
Run Code Online (Sandbox Code Playgroud)
但是,您的示例是在非常C#样式中使用F#,因此代码看起来并不是非常优雅,并且它可能无法为您提供函数式编程的许多好处.
如果我想表示你正在使用的结构,那么我可能不会在类型中添加对类型的引用Album.当您在a中放置一个专辑列表时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
Run Code Online (Sandbox Code Playgroud)