当唯一的差异是一个变量的类型时,重构重复的代码?

JK.*_*JK. 4 c# api refactoring code-duplication

我必须能够连接到两个不同版本的API(1.4和1.5),我们称之为Foo API.我连接到API并处理结果的代码基本上是重复的 - 唯一的区别是从两个API返回的数据类型.我怎样才能重构这个以消除重复?

在Foo14Connector.cs(我自己的类中调用1.4 API)

public class Foo14Connector
{
    public void GetAllCustomers() 
    {
        var _foo = new Foo14WebReference.FooService();
        Foo14WebReference.customerEntity[] customers = _foo.getCustomerList;
        foreach (Foo14WebReference.customerEntity customer in customers)
        {
            GetSingleCustomer(customer);
        }
    }
    public void GetSingleCustomer(Foo14WebReference.customerEntity customer)
    {
        var id = customer.foo_id;
        // etc 
    }
}
Run Code Online (Sandbox Code Playgroud)

在几乎完全重复的类Foo15Connector.cs(我自己的类调用1.5 API)中

public class Foo15Connector
{
    public void GetAllCustomers() 
    {
        var _foo = new Foo15WebReference.FooService();
        Foo15WebReference.customerEntity[] customers = _foo.getCustomerList;
        foreach (Foo15WebReference.customerEntity customer in customers)
        {
            GetSingleCustomer(customer);
        }
    }
    public void GetSingleCustomer(Foo15WebReference.customerEntity customer)
    {
        var id = customer.foo_id;
        // etc 
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我必须有两个不同的连接器,因为API上的一个单个方法调用(数百个)在1.5中有一个新参数.

类Foo14WebReference.customerEntity和Foo15WebReference.customerEntity都具有相同的属性.

com*_*ech 5

如果连接器位于不同的项目中,这是一个容易解决的问题:

添加一个新的类文件,称之为ConnectorCommon并复制所有公共代码,但删除了名称空间.将此类设为部分类,并将类(而不是文件)重命名为Connector.

您需要为每个项目添加一个链接.

接下来,从当前连接器类中删除所有代码,将类(不一定是文件)重命名为与partial类相同,并添加引用命名空间的using语句.

这应该得到你想要的.

所以,当你完成后,你将拥有:

文件连接器公共:

public partial class Connector
{
    public void GetAllCustomers() 
    {
        var _foo = new FooService();
        customerEntity[] customers = _foo.getCustomerList;
        foreach (customerEntity customer in customers)
        {
            GetSingleCustomer(customer);
        }
    }
    public void GetSingleCustomer(customerEntity customer)
    {
        var id = customer.foo_id;
        // etc 
    }
}
Run Code Online (Sandbox Code Playgroud)

文件Magento15Connector

using Foo15WebReference;

partial class Connector
{
}
Run Code Online (Sandbox Code Playgroud)

文件Magento14Connector

using Foo14WebReference;

partial class Connector
{
}
Run Code Online (Sandbox Code Playgroud)

更新

这个过程起初可能有点混乱.

为了澄清,您将在两个项目之间的公共文件中共享源代码.

实际的类是每个项目中具有命名空间的特定类.您可以使用partial关键字将公共文件与每个项目中的实际项目文件(即Magneto14)组合在一起,以便在编译时在该项目中创建完整的类.

最棘手的部分是将公共文件添加到两个项目中.

为此,请Add Existing Item...在第二个项目中选择菜单,导航到公共文件,然后单击Add按钮旁边的右箭头.

从下拉菜单中选择Add as link.这将向第二个项目添加对该文件的引用.源代码将包含在两个项目中,对公共文件的任何更改都将在两个项目中自动提供.

更新2

我有时会忘记VB如何轻松地完成这样的任务,因为那是我普通的编程环境.

为了在C#中完成这项工作,还有一个必须采用的技巧:Conditional compilation symbols.它使公共代码的开始比我想要的更冗长,但它仍然确保您可以使用一组公共代码.

要使用此技巧,请为每个项目添加一个条件编译符号(确保为其设置All Configurations).例如,在Magento14项目中添加Ver14并在Magento15项目中添加Ver15.

然后在公共文件中,使用类似于以下内容的结构替换命名空间:

#if Ver14
using Magneto14;
namespace Magento14Project

#elif Ver15
using Magneto15;
namespace Magento15Project

#endif
Run Code Online (Sandbox Code Playgroud)

这将确保根据编译公共代码的项目包含正确的命名空间和用法.

请注意,所有常用using语句都应保留在公共文件中(即足以使其编译).