F# 介面中的F和泛型类型

F# 介面中的F和泛型类型,f#,F#,我有一个简单的接口,由几个类实现,所以接口看起来像: type IResponseBuilder = abstract member FillMessangeFrame<'TResponse> : MessageHeader -> byte array -> Option<'TResponse> type ModuleIdentyfication() = inherit UdpBaseFrame.BaseFrame() in

我有一个简单的接口,由几个类实现,所以接口看起来像:

type IResponseBuilder = 
   abstract member FillMessangeFrame<'TResponse> : MessageHeader -> byte array -> Option<'TResponse>
type ModuleIdentyfication() =
    inherit UdpBaseFrame.BaseFrame()     
    interface IResponseBuilder with

        member this.FillMessangeFrame (header: MessageHeader) (frame: byte array) : Option<'TResponse> = 
            let unknownFrame (msg:string) = msg |> Mediator.UpdMediator.Instance.InvokeUpdDebugLog |> logger.Info
            let messange = ModuleIdentyfiationResponsetMessage()
            match frame <> null, frame.Length >= int header.length with
            | true, true -> 
                let message : Option<ModuleIdentyfiationResponsetMessage> = UdpBaseFrame.Deserialize(frame, 0, messange); 
                message
            | false, _ | _, false -> unknownFrame (sprintf "Unknown or empty header, full frame content:%s" (BitConverter.ToString(frame))); None
正如您所看到的,填充消息框架返回泛型类型,因为它在其中实现的每个类型都返回不同的类型,类型如下所示:

type IResponseBuilder = 
   abstract member FillMessangeFrame<'TResponse> : MessageHeader -> byte array -> Option<'TResponse>
type ModuleIdentyfication() =
    inherit UdpBaseFrame.BaseFrame()     
    interface IResponseBuilder with

        member this.FillMessangeFrame (header: MessageHeader) (frame: byte array) : Option<'TResponse> = 
            let unknownFrame (msg:string) = msg |> Mediator.UpdMediator.Instance.InvokeUpdDebugLog |> logger.Info
            let messange = ModuleIdentyfiationResponsetMessage()
            match frame <> null, frame.Length >= int header.length with
            | true, true -> 
                let message : Option<ModuleIdentyfiationResponsetMessage> = UdpBaseFrame.Deserialize(frame, 0, messange); 
                message
            | false, _ | _, false -> unknownFrame (sprintf "Unknown or empty header, full frame content:%s" (BitConverter.ToString(frame))); None
所以,正如您看到的,当我以字节数组的形式接收消息时,我将其反序列化为某种类型,我想将其作为这种类型返回,但它告诉我这里的类型不匹配

message <- problem
我试着把它调高到

message :> Option<'TResponse> 

但是运气不好,返回值不匹配

当您以这种方式定义接口时,您的意思是fillmesangeframe方法是泛型的,并且该方法的调用方可以确定泛型类型参数是什么。但是,这不是您想要的-ModuleIdentity中的实现总是返回一种特定类型的消息-即您的ModuleIdentityFicationResponseMessage,而方法的调用方对此没有控制权

相反,您需要将接口定义为泛型。这样,您就可以为特定类型的消息实现接口,而实现该接口的类将控制该类型:

type IResponseBuilder<'TResponse> = 
  abstract member FillMessangeFrame : MessageHeader -> byte array -> Option<'TResponse>
类型检查的虚拟实现:

type ModuleIdentyfication() =
  interface IResponseBuilder<ModuleIdentyfiationResponsetMessage> with
    member this.FillMessangeFrame (header: MessageHeader) (frame: byte array) : Option<_> = 
        Some(ModuleIdentyfiationResponsetMessage())

当您以这种方式定义接口时,您的意思是FillMessangeFrame方法是泛型的,并且该方法的调用方可以确定泛型类型参数是什么。但是,这不是您想要的-ModuleIdentity中的实现总是返回一种特定类型的消息-即您的ModuleIdentityFicationResponseMessage,而方法的调用方对此没有控制权

相反,您需要将接口定义为泛型。这样,您就可以为特定类型的消息实现接口,而实现该接口的类将控制该类型:

type IResponseBuilder<'TResponse> = 
  abstract member FillMessangeFrame : MessageHeader -> byte array -> Option<'TResponse>
类型检查的虚拟实现:

type ModuleIdentyfication() =
  interface IResponseBuilder<ModuleIdentyfiationResponsetMessage> with
    member this.FillMessangeFrame (header: MessageHeader) (frame: byte array) : Option<_> = 
        Some(ModuleIdentyfiationResponsetMessage())