如何使用Generics清理此代码?

时间:2016-07-12 16:19:57

标签: c# generics

我正在构建一组WCF服务,我总是要做的一件事就是在每个操作结束时创建响应消息。
我目前有一个Mapper类,其中包含许多这些创建方法(30+并且正在计数),但我确信我可以对Generics执行相同的操作。

这些方法的几个例子如下:

    public ClientResponse CreateClientResponse(Header inboundHeader, ClientData data)
    {
        var response = new ClientResponse () {
            Header = inboundHeader,
            Data = data
        };

        return response;
    }

    public OrderResponse CreateOrderResponse(GenericHeader inboundHeader, List<OrderData> data)
    {
        var response = new OrderResponse() {
            Header = inboundHeader,
            Data = data
        };

        return response;
    }

ClientResponseOrderResponse当前未以任何方式连接,但在方法/属性等方面看起来都相同:

public class ClientResponse
{
    public ClientResponse()
    {
        Header = new GenericHeader();
        Data = new ClientData();
    }

    [DataMember(IsRequired = true)]
    public GenericHeader Header { get; set; }

    [DataMember(IsRequired = true)]
    public ClientData Data {get; set;}
}

我的第一次尝试是引入一个具有两个属性的IResponse<T>,并将其添加到响应类中:

public interface IResponse<T>
{
    GenericHeader Header { get; set; }
    T Data { get; set; }
}

然后在我的Generic方法中使用它:

public TOut CreateResponse<TOut, TIn>(GenericHeader inboundHeader, TIn data) where TOut : new()
{
    var response = new TOut();
    response.Header = inboundHeader;
    response.Data = data;
    return response;
}

所以我可以这样称呼它:

var result = CreateResponse<ClientResponse, ClientData>(new GenericHeader(), new ClientData());

可是... 显然,泛型代码不起作用,因为TOut并不了解HeaderData属性。

我想我需要在这里使用界面,但我迷路了,如果我要改变它,我不确定如何返回TOut的具体类界面。

感激不尽的任何帮助。

1 个答案:

答案 0 :(得分:0)

为您的回复添加标头通用参数。然后,您可能希望使用流畅的构建器语法来实现美观(此处未包含)。

public interface IResponse<TData,THeader>
{
    THeader Header { get; set; }
    TData Data { get; set; }
}

public TOut CreateResponse<TOut, TIn,THeader>(TIn data) 
    where TOut : IResponse<TIn,THeader>,new(), THeader: new()
    => new TOut(){ Header = new THeader(), Data = data,};

var result = CreateResponse<ClientResponse, ClientData,GenericHeader>(new ClientData());