Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 两个我不知道的第三方类的通用接口';我无法控制。外部多态性?_C#_Web Services_Design Patterns_Interface_Wrapper - Fatal编程技术网

C# 两个我不知道的第三方类的通用接口';我无法控制。外部多态性?

C# 两个我不知道的第三方类的通用接口';我无法控制。外部多态性?,c#,web-services,design-patterns,interface,wrapper,C#,Web Services,Design Patterns,Interface,Wrapper,我需要一个小方向。C#的新成员 我正在使用包装web服务的第三方开发工具包。我处理的两个特定类虽然相对相似,但它们位于dev工具包中的两个不同名称空间中,并且没有通用的基类。不过,我想为他们两个编写一个通用接口的程序。我无意中拼凑了一个基本上包装包装器的实现,但我确信由于不断的类型转换,它不是最有效的方法 我一直在钻研关于适配器、接口、扩展方法等的文章,但我的时间不够,所以如果我能在一个方向上取得进展,我将不胜感激 using ThirdParty.TypeA.Employee; using T

我需要一个小方向。C#的新成员

我正在使用包装web服务的第三方开发工具包。我处理的两个特定类虽然相对相似,但它们位于dev工具包中的两个不同名称空间中,并且没有通用的基类。不过,我想为他们两个编写一个通用接口的程序。我无意中拼凑了一个基本上包装包装器的实现,但我确信由于不断的类型转换,它不是最有效的方法

我一直在钻研关于适配器、接口、扩展方法等的文章,但我的时间不够,所以如果我能在一个方向上取得进展,我将不胜感激

using ThirdParty.TypeA.Employee;
using ThirdParty.TypeB.Employee;

public class Employee
{
     private object genericEmployee;

     private EmployeeType empType;

     public enum EmployeeType
     {
          TypeA = 0;
          TypeB = 1;
     }   

     public Employee(Object employee, EmployeeType type)
     {
         genericEmployee = employee;
         empType = type;
     }

     public String Name
     {
         if (empType == EmployeeType.TypeA)
             return (ThirdParty.TypeA.Employee)genericEmployee.Name;
         else
             return (ThirdParty.TypeB.Employee)genericEmployee.Name;
     }

     public String Age
     {
         if (empType == EmployeeType.TypeA)
             return (ThirdParty.TypeA.Employee)genericEmployee.Age;
         else
             return (ThirdParty.TypeB.Employee)genericEmployee.Age;
     }
 }
第2版:

class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter
{
    TypeA _employee;
    public EmployeeTypeAAdapter(TypeA employee) 
    { 
         _employee = employee
    }

     public String Name
     {
        get { return _employee.Name; }  
        set { _employee.Name = value; }
     } 

      public String Balance
      {
        get
        {
            if (_employee.Balance != null)
            {
                decimal c = _employee.Balance.Amount;
                return String.Format("{0:C}", c);
            }
            else
            {
                return "";
            }
          }
       }  

       //...
}

class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter
{
    TypeB _employee;
    public EmployeeTypeAAdapter(TypeB employee) 
    { 
         _employee = employee
    }

     public String Name
     {
        get { return _employee.Name; }  
        set { _employee.Name = value; }
     } 

      public String Balance
      {
        get
        {
            if (_employee.Balance != null)
            {
                decimal c = _employee.Balance.Amount;
                return String.Format("{0:C}", c);
            }
            else
            {
                return "";
            }
          }
       }  

     //....
}
尝试以下方法:

public interface IEmployeeAdapter
{
    string Age { get; set; }
    string Name { get; set; }
}

class EmployeeTypeAAdapter : TypeA, IEmployeeAdapter
{
    public EmployeeTypeAAdapter(TypeA employee) { }
}

class EmployeeTypeBAdapter : TypeB, IEmployeeAdapter
{
    public EmployeeTypeBAdapter(TypeB employee) { }
}

public static class EmployeeAdapterFactory
{
    public static IEmployeeAdapter CreateAdapter(object employee, EmployeeType type)
    {
        switch (type)
        {
            case EmployeeType.TypeA: return new EmployeeTypeAAdapter((TypeA)employee);
            case EmployeeType.TypeB: return new EmployeeTypeBAdapter((TypeB)employee);
        }
    }

    // or without enum

    public static IEmployeeAdapter CreateAdapter(object employee)
    {
        if (employee is TypeA) return new EmployeeTypeAAdapter((TypeA)employee);
        if (employee is TypeB) return new EmployeeTypeABdapter((TypeB)employee);
    }

    // or better introduce sort of type map
}

另一个合适的名字是EmployeeProxy,正如你喜欢的那样。

你想做的事情被称为。您可以使用适配器类和共享接口来实现这一点,但是手动创建这些适配器需要大量重复的粘合代码。编写粘合代码的一种方法是动态构造适配器类型。你可以通过IL发射来做这件事(如果你以前从来没有机会玩过这个游戏,尽管有很多的边界案例需要考虑)。但是,如果你只是想让它工作,你可以把它作为开始的地方。C#‘dynamic’类型也可以使用(并最终在幕后生成一些相同的代码),但它并没有给您一个参考,您可以像传递接口类型一样传递非动态代码。

TypeA和TypeB是公共的和众所周知的,我的意思是您真的需要引入enum吗?你可以用一种泛型的方法。TypeA和TypeB的类型是什么,类是如何声明的?只是一组相等的属性而没有基类?因此,您只能通过
对象
来泛化它们?第三方库中没有基类。枚举只是一个方便的属性,我创建它是为了避免每次访问属性时都必须使用TypeOf或IS来确定对象的类型(TypeA或TypeB)。然后我会返回上面详述的适配器中的属性吗?考虑到两个对象(TypeA和TypeB)是如何99%相同的(30个属性/方法中可能有一个或两个具有不同的名称),并且只有类型上的真正区别(一个是ThirdPartyAdaptor.TypeA.Employee类型,另一个是ThirdPartyAdaptor.TypeB.Employee类型),这似乎会创建几乎重复的类。见上文第2版。@RyanMac:那么困难是什么?对不起,我没听懂你的话。您将所有共享属性放入接口中,它将自动实现。如果一个属性名在基础类型和接口上不同,您可以“帮助”正确实现/匹配它。@RyanMac:如果我缺少一些OO概念,您还可以引入一个包含共享属性和其他帮助器方法的抽象基类。问题在于,在将每个属性返回给客户机之前,我通常需要对其执行一些实现代码(上面的Balance属性就是一个例子)。我假设这个逻辑将进入适配器,唯一的问题是,它必须进入TypeA和TypeB的适配器,创建两个基本相同的类。我认为我需要的是一个基类(似乎应该存在于第三方库中,但不存在),它将封装所有共享实现逻辑。这有帮助吗?@EricEskildsen:如果你只想公开其中的一些属性,你必须手工编写每个属性。但是,如果您想公开所有项目并自动进行尝试,请告诉我该项目的内容,请: