【问题标题】:C# Generics type inference for comman常见的 C# 泛型类型推断
【发布时间】:2016-07-04 15:46:54
【问题描述】:

我必须使用我无法控制的特定 API:

TResponse Request<TRequest, TResponse>(TRequest request) 
    where TRequest : class 
    where TResponse : class;

这是来自 EasyNetQ 库的 RabbitMq 的 RPC 包装器

我想有一些方法来定义 TRequest 到 TResponse 的关系,这样我就不必像这样每次调用都手动匹配它们:

this._client.Request<CancelPaymentByMerchantRequest, CancelPaymentByMerchantResponse>(request);

我想出的解决办法是:

public interface ICommand<TRequest, TResponse> { }

public class StartCommand : ICommand<StartCommand, StartResponse>
{
    public int Id { get; set; }

    public string Args { get; set; }
}

public class StartResponse
{
    public bool Success { get; set; }

    public string Error { get; set; }
}

还有一个消费者:

 public TResponse Send<TRequest, TResponse>(ICommand<TRequest, TResponse> payload)
            where TRequest : class
            where TResponse : class
        {
            var result = client.Request<TRequest, TResponse>((TRequest)payload);
            return result;
        }

是否可以摆脱 ICommand 标记界面上的 TRequest 类型?

我还担心与标记接口相关的额外成本,然后在实际的库调用中直接从它进行转换。

任何建议将不胜感激。

【问题讨论】:

    标签: c# .net easynetq


    【解决方案1】:

    实现这一点的最简单方法是在 Send 周围添加一个抽象,每个 TRequest 类型:

    public SpecificResponse Send(SpecificRequest payload)
    {
        return Send<SpecificRequest, SpecificResponse>(payload);
    }
    

    您必须为每个 TRequest, TResponse 对定义 Send 的重载,但随后您的应用程序的其余部分可以使用这些“强类型”版本,以避免必须在任何地方重述关系。

    如何编排这取决于您,但我更喜欢每个请求/响应类型的接口/类,它充当通用层的中介(或者,一个带有一堆合同的大接口可以像好)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多