使用具有两种类型但具有不同名称的API。我如何重用我的代码?

时间:2013-11-21 11:26:54

标签: c# .net generics types .net-3.5

我正在使用一个Web服务,它返回两种完全相同的类型但被称为两种不同的东西(是的,我知道的API很棒......)。一种称为SearchKMQueryResponse,另一种称为TopSolutionsKMQueryResponse。我将这些类型的输出映射到我自己的模型类中,并且必须使用两个采用不同参数类型的方法,但返回相同的类型。这两种API类型继承object类型,因此我无法将基类型作为参数传递。他们没有通过API公开接口,所以我也搞砸了。

那么有一个优雅的解决方案可以停止在下面的代码中重复自己吗? ...

编辑:我正在使用.Net v3.5来解决此问题。

      public static KmSearchResponse Map(SearchKMQueryResponse response)
    {
        if (response == null)
        {
            return null;
        }
        else
        {
            var myResponse = new KmSearchResponse()
            {
                CountTotal = long.Parse(response.model.instance.resultlist.resultlist[0].Value),
                Message = response.message,
                Status = (MyProject.Model.StatusType)response.status,
            };

            for (var startID = 2; startID < (myResponse.CountTotal * 5); startID += 5)
            {
                myResponse.Results.Add(
                    KmSearchResponseResultsMapper.Map(
                    response.model.instance.resultlist.resultlist, startID)
                    );
            }

            myResponse.Count = myResponse.Results.Count;

            return myResponse;
        }
    }

    public static KmSearchResponse Map(TopSolutionsKMQueryResponse response)
    {
        if (response == null)
        {
            return null;
        }
        else
        {
            var myResponse = new KmSearchResponse()
            {
                CountTotal = long.Parse(response.model.instance.resultlist.resultlist[0].Value),
                Message = response.message,
                Status = (MyProject.Model.StatusType)response.status,
            };

            for (var startID = 2; startID < (myResponse.CountTotal * 5); startID += 5)
            {
                myResponse.Results.Add(
                    KmSearchResponseResultsMapper.Map(
                    response.model.instance.resultlist.resultlist, startID)
                    );
            }

            myResponse.Count = myResponse.Results.Count;

            return myResponse;
        }
    }

3 个答案:

答案 0 :(得分:6)

我假设生成了SearchKMQueryResponseTopSolutionsKMQueryResponse WCF数据合同。这些是作为部分类生成的,因此您可以为应用接口的地方编写另一部分:

IQueryResponse
{
    SomeModel model { get; set; }
    SomeMessage message { get; set; }
    SomeStatus status { get; set; }
}

public partial class SearchKMQueryResponse : IQueryResponse { }
public partial class TopSolutionsKMQueryResponse : IQueryResponse { }

现在您可以更改映射器以接受接口作为输入:

KmSearchResponse Map(IQueryResponse response)

答案 1 :(得分:1)

我的直觉反应是说“保持原样” - 您无法控制API,因此可能有一天不同的类包含不同的属性。如果那一天到来,你将不得不取消将两者合并在一起的代码。

您还没有指定每个API响应类中的属性类型是否相同,或者它们是否也是使用相同命名系统的单独类。如果 不同,那么任何形式的基类或接口都无法提供帮助。

我将为KmSearchResponse创建两个额外的构造函数,一个接受类型为SearchKMQueryResponse的参数,另一个接受类型为TopSolutionsKMQueryResponse的参数。然后,每个构造函数都可以提取出所需的字段。

答案 2 :(得分:0)

你可以使用动态关键字,但你不会得到任何智能感知。

http://www.hanselman.com/blog/C4AndTheDynamicKeywordWhirlwindTourAroundNET4AndVisualStudio2010Beta1.aspx

编辑:或者你可以为每个类编写一个强类型的包装器并共享一个基类型