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