首页 > 解决方案 > GRPC - 为什么`CallInvoker`需要强加`TRequest:class`和`TResponse:class`?

问题描述

抽象类定义的签名对和CallInvokerGrpc.Core施加了类型约束。这可以防止使用结构作为远程方法的响应,例如,它不适用于 F# 结果类型作为响应类型,因为 F#是结构类型。classTRequestTResponseResult<'a, 'b>Result<_, _>

为什么CallInvoker需要强加TRequest: classand TResponse: class

https://github.com/grpc/grpc/blob/master/src/csharp/Grpc.Core.Api/CallInvoker.cs

标签: .netf#grpc

解决方案


我过去看过这个,因为我想建议为 protobuf-net.Grpc 删除它(它适用于 F#,顺便说一句);没有根本原因,除了代码null在许多地方使用哨兵有意义 - 所有这些场景都需要改变,大概是编码“有值”和“价值”的元组类型(基本上Nullable<T>但对于任何T) ; 这是相当多的工作。

不过,我愿意尝试一下;它实际上可能比我为 protobuf-net.Grpc 计划的解决方法更容易(涉及动态包装值类型)。

现在,您必须使用 F# 引用类型。例如,这适用于 protobuf-net.Grpc

[<DataContract; CLIMutable>]
type MultiplyRequest =
    { [<DataMember(Order = 1)>] X : int
      [<DataMember(Order = 2)>] Y : int }

[<DataContract; CLIMutable>]
type MultiplyResult =
    { [<DataMember(Order = 1)>] Result : int }

[<ServiceContract(Name = "Hyper.Calculator")>]
type ICalculator =
    abstract MultiplyAsync : MultiplyRequest -> ValueTask<MultiplyResult>

推荐阅读