因此,当我在我的F#代码中创建一些属性时,因为F#不支持自动属性,据我所知.我必须创建支持字段并将它们初始化为null,这在函数式编程术语中似乎不正确.例如
let mutable albums : DbSet = null
let mutable genres : DbSet = null
member x.Albums
with get() = albums
and set(value) = albums <- value
member x.Genres
with get() = genres
and set (value) = genres <- value
Run Code Online (Sandbox Code Playgroud)
这样做有更好的方法吗?非常感谢你的建议.
Tom*_*cek 10
当您需要可变属性时,F#不支持自动属性,但是当您只需要readonly属性时,它支持轻量级语法.如果您正在编写一些功能代码,那么使用readonly属性可能实际上更合适:
type Music(genres : DbSet, albums : DbSet) =
member x.Albums = albums
member x.Genres = genres
Run Code Online (Sandbox Code Playgroud)
这与pad建议的记录基本相同,但如果您希望更好地控制类型的外观(以及它们在C#中的显示方式或数据绑定方式),则可能更合适.
如果DbSet
是一个可变类型,那么你可能只需使用上面的类型并初始化它一次(你仍然可以修改DbSet
值).如果要更改该DbSet
值,可以添加一个返回克隆对象的方法:
member x.WithAlbums(newAlbums) =
Music(genres, newAlbums)
Run Code Online (Sandbox Code Playgroud)
使用null
或Unchecked.defaultOf<_>
在F#中被认为是一种非常糟糕的做法,你应该总是尝试创建完全初始化的对象.如果该值可能丢失,您可以使用option
type来表示该值,但是您必须始终为缺失值编写处理程序,以使程序安全.
除非你做一些复杂的事情,否则我建议使用记录而不是类.基本上,它们是具有额外功能的类:不变性,结构相等,模式匹配等:
type Playlists = {
Albums: DbSet;
Genres: DbSet
}
Run Code Online (Sandbox Code Playgroud)
您可以轻松获取记录的字段:
let p = {Albums = ...; Genres = ...}
let albums = p.Albums
let genres = p.Genres
Run Code Online (Sandbox Code Playgroud)
在默认记录中,字段是不可变的; 你可以在记录中声明可变字段,但这被认为是一种不好的做法.虽然您无法设置属性,但可以使用旧记录创建新记录.默认的不变性通常不是问题,而且它使代码更具功能性,更容易推理:
let p = {Albums = a; Genres = g}
// Create new records by updating one field
let p1 = {p with Albums = a1}
let p2 = {p with Genres = g2}
Run Code Online (Sandbox Code Playgroud)
如果您坚持创建类,建议使用带有显式参数的构造函数:
type Playlists(a: DbSet, g: DbSet) =
let mutable albums = a
let mutable genres = g
// ...
Run Code Online (Sandbox Code Playgroud)
当需要默认构造函数时,可以使用Unchecked.default<'T>
非可空字段,或者更好地使用它们的默认构造函数:
// Set fields using dump values
let mutable albums = new DbSet()
let mutable genres = new DbSet()
Run Code Online (Sandbox Code Playgroud)
但请确保在实际使用它们之前设置这些字段.
仅供参考 - 计划用于F#3.0的自动属性.请参阅预览文档[MSDN].看起来你的例子会变成:
type Music() =
member val Albums : DbSet = null with get, set
member val Genres : DbSet = null with get, set
Run Code Online (Sandbox Code Playgroud)