最近、型宣言でメンバー制約が使用されているという同様の質問がありました。
サンプルを修正してコンパイルする方法はわかりませんが、それが不可能な場合でも驚かないでしょう。メンバー制約は、静的に解決された型パラメーター、特にinline
関数またはメンバーで使用するように設計されており、クラスの型パラメーターで使用するのは慣用的なF#コードではないと思います。
あなたの例に対するより慣用的な解決策は、インターフェースを定義することだと思います。
type INamed =
abstract Name : string
type ListEntryViewModel<'T when 'T :> INamed>(model:'T) =
member this.Name = model.Name
(実際、ListEntryViewModel
おそらく型パラメーターは必要なくINamed
、コンストラクターパラメーターとして使用できますが、このように記述することにはいくつかの利点があるかもしれません。)
これで、ダックタイピングを使用ListEntryViewModel
して、プロパティを持つもので使用できますが、インターフェイスName
は実装しません。INamed
これは、静的メンバー制約をinline
返し、使用して既存のプロパティをキャプチャする関数を作成することで実行できます。INamed
Name
let inline namedModel< ^T when ^T : (member Name : string)> (model:^T)=
{ new INamed with
member x.Name =
(^T : (member Name : string) model) }
次に、インターフェイスを実装する必要はなく、プロパティのみが必要なListEntryViewModel(namedModel someObj)
場所を記述して、ビューモデルを作成できます。someObj
Name
インターフェイスを使用することで、モデルから必要なものをより適切に文書化できるため、このスタイルをお勧めします。スキームに適合しない他のオブジェクトがある場合は、それらを適応させることができますが、モデルを作成している場合は、インターフェイスを実装することで、必要なすべての機能を確実に公開できます。