Как написать тип оболочки для нескольких интерфейсов, общих для некоторых типов - PullRequest
0 голосов
/ 24 апреля 2019

Я хочу написать общий код для разных типов без создания одного базового типа для него. Его типы реализуют несколько интерфейсов, которые нужны общему коду. Это способ или он не подходит для модели f # type?

type IInterface1 =
    abstract member id :string

type IInterface2 = 
    abstract member weight :float

type A (id, weight) =
    interface IInterface1 with member x.id = id
    interface IInterface2 with member x.weight = weight

type B (id, weight) =
    interface IInterface1 with member x.id = id
    interface IInterface2 with member x.weight = weight

type Common<'T when 'T :> IInterface1 and 'T :> IInterface2> (o :'T) =
    interface IInterface1 with member x.id = o.id
    interface IInterface2 with member x.weight = o.weight

type LBranch<'T> (root :'T) =
    member val root = root
    member val branch = [root] :'T list with get, set
    member x.add item = x.branch <- item :: x.branch; x
    member x.head = match x.branch with h :: _ -> h | _ -> failwith "LevelingTree corrupt"

let a, b = A("1", 10.0), B("2", 100.0)
let ca, cb = Common(a), Common(b)
LBranch(ca).add(cb) // Common<B> is not compatible with Common<A>

Простое решение, которое я нашел, не хорошо, но работает:

type Common (o :obj) =
    interface IInterface1 with member x.id = match o with :? IInterface1 as o -> o.id | _ -> failwith ""
    interface IInterface2 with member x.weight = match o with :? IInterface2 as o -> o.weight | _ -> failwith ""

1 Ответ

1 голос
/ 24 апреля 2019

Реальное простое решение состоит в том, чтобы сложный интерфейс наследовал базовые интерфейсы, т.е.

type IInterface1 =
    abstract member id :string

type IInterface2 = 
    abstract member weight :float

type ICommon =
    inherit IInterface1
    inherit IInterface2

Также см. MSDN .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...