Property Design F #

Therefore, when I ever create some properties in my F # code, because F # does not support auto properties, as far as I know. I have to create support fields and initialize them to zero, which does not seem right in functional programming. E.g.

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 

Is there a better way to do this? Thanks so much for your suggestions.

+6
source share
3 answers

F # does not support automatic properties when you need a mutable property, but it supports easy syntax when you only need a readonly property. If you are writing any kind of functional code, then using readonly properties might be more appropriate:

 type Music(genres : DbSet, albums : DbSet) = member x.Albums = albums member x.Genres = genres 

This is essentially the same as the entries suggested by the pad, but may be more appropriate if you want to better control how types look (and how they appear in C # or for data binding).

If the DbSet is a mutable type, you can probably just use the above type and initialize it only once (you can still change the values โ€‹โ€‹of the DbSet ). If you want to change the value of DbSet , you can add a method that returns the cloned object:

  member x.WithAlbums(newAlbums) = Music(genres, newAlbums) 

Using null or Unchecked.defaultOf<_> in F # is considered very bad practice, and you should always try to create a fully initialized object. If the value may be missing, you can use the option type to represent it, but then you should always write a handler for the missing value to make your program safe.

+10
source

If you are not doing something complicated, I would recommend using records instead of classes. In principle, these are classes with additional functions: immutability, structural equality, pattern matching, etc .:

 type Playlists = { Albums: DbSet; Genres: DbSet } 

You can easily get the record fields:

 let p = {Albums = ...; Genres = ...} let albums = p.Albums let genres = p.Genres 

By default, fields in records are immutable; you can declare mutable fields in records, but this is considered bad practice. Although you cannot set properties, you can create a new entry from the old one. The default continuity is usually not a problem, in addition, it makes the code more functional and understandable:

  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} 

If you insist on creating classes, it is recommended to use a constructor with explicit parameters:

 type Playlists(a: DbSet, g: DbSet) = let mutable albums = a let mutable genres = g // ... 

If a default constructor is needed, you can use Unchecked.default<'T> for fields with invalid values โ€‹โ€‹or it is better to use their default constructors:

  // Set fields using dump values let mutable albums = new DbSet() let mutable genres = new DbSet() 

But make sure you set these fields before actually using them.

+5
source

FYI - automatic properties planned for F # 3.0. See preview documentation [MSDN] . It looks like your example will be as follows:

 type Music() = member val Albums : DbSet = null with get, set member val Genres : DbSet = null with get, set 
+5
source

Source: https://habr.com/ru/post/907912/


All Articles