Ostatnio było podobne pytanie, gdzie member constraints were used in the type declaration.
Nie jestem pewien, jak poprawić próbkę, aby ją skompilować, ale nie byłbym zaskoczony, gdyby to było niemożliwe. Więzy członkowskie są zaprojektowane do użycia z parametrami statycznie rozdzielonymi, a zwłaszcza z funkcjami lub członkami inline
i nie uważam, że jest to fikcyjny kod F #, który używałby ich z parametrami typu klasy.
myślę, że bardziej idiomatyczne rozwiązanie do przykładu byłoby zdefiniowanie interfejsu:
type INamed =
abstract Name : string
type ListEntryViewModel<'T when 'T :> INamed>(model:'T) =
member this.Name = model.Name
(W rzeczywistości, ListEntryViewModel
prawdopodobnie nie potrzebujesz parametr typu i może po prostu wziąć INamed
jako parametr konstruktora , ale mogą istnieć pewne korzyści w formie pisemnej go w ten sposób.)
teraz można nadal korzystać z kaczki pisanie i użyć ListEntryViewModel
na rzeczy, które mają Name
nieruchomość, ale nie implementować interfejs INamed
! Można to zrobić pisząc inline
funkcję zwracającą INamed
i używa ograniczeń członków statycznych uchwycić istniejące Name
właściwość:
let inline namedModel< ^T when ^T : (member Name : string)> (model:^T)=
{ new INamed with
member x.Name =
(^T : (member Name : string) model) }
Następnie można utworzyć widoku modelu pisząc ListEntryViewModel(namedModel someObj)
gdzie someObj
nie musi implementować interfejs , ale potrzebuje tylko własności Name
.
Wolałbym ten styl, ponieważ dzięki zastosowaniu interfejsu można lepiej dokumentować to, czego wymaga się od modelu. Jeśli masz inne obiekty, które nie pasują do schematu, możesz je dostosować, ale jeśli piszesz model, implementacja interfejsu jest dobrym sposobem, aby upewnić się, że eksponuje wszystkie wymagane funkcje.
Należy zauważyć, że nie jest to naprawdę "pisanie na maszynie", ale raczej pisanie strukturalne (pod). – Eyvind