我正在使用第三方的网络服务,我遇到了一个小麻烦。在我手动创建一个方法将每个属性从源复制到目标之前,我想我会在这里要求更好的解决方案。
我有两个对象,一个是Customer.CustomerParty,另一个是Appointment.CustomerParty。 CustomerParty对象实际上是属性和子对象完全相同。但是我无法从1推到另一个。
所以,我需要从网络服务中找到某个人。我可以通过调用Customer.FindCustomer(customerID)来做到这一点,并返回一个Customer.CustomerParty对象。
我需要接受我找到的那个人,然后在“CreateAppointment”请求中使用它们几行。 Appointment.CreateAppointment接受约会对象,约会对象包含CustomerParty对象。
但是,它想要的CustomerParty对象实际上是Appointment.CustomerParty。我有一个Customer.CustomerParty。
明白我的意思?有什么建议吗?
答案 0 :(得分:12)
为什么不使用AutoMapper?然后你可以这样做:
TheirCustomerPartyClass source = WebService.ItsPartyTime();
YourCustomerPartyClass converted =
Mapper.Map<TheirCustomerPartyClass, YourCustomerPartyClass>(source);
TheirCustomerPartyClass original =
Mapper.Map<YourCustomerPartyClass, TheirCustomerPartyClass>(converted);
只要属性相同,您就可以创建一个非常简单的地图:
Mapper.CreateMap<TheirCustomerPartyClass, YourCustomerPartyClass>();
Mapper.CreateMap<YourCustomerPartyClass, TheirCustomerPartyClass>();
答案 1 :(得分:9)
在编写域模式时,这种情况很常见。您基本上需要在两个对象之间编写域转换器。您可以通过多种方式执行此操作,但我建议在目标类型中使用重写的构造函数(或静态方法)来获取服务类型并执行映射。由于它们是两种CLR类型,因此您无法直接从一种类型转换为另一种类型。您需要逐个成员复制。
public class ClientType
{
public string FieldOne { get; set; }
public string FieldTwo { get; set; }
public ClientType()
{
}
public ClientType( ServiceType serviceType )
{
this.FieldOne = serviceType.FieldOne;
this.FieldTwo = serviceType.FieldTwo;
}
}
或者
public static class DomainTranslator
{
public static ServiceType Translate( ClientType type )
{
return new ServiceType { FieldOne = type.FieldOne, FieldTwo = type.FieldTwo };
}
}
答案 2 :(得分:1)
我正在使用第三方的一套 web服务...
假设您无法修改类,我不知道您可以通过何种方式更改转换行为。至少,没有办法不远,比编写CustomerToAppointmentPartyTranslator()映射函数复杂得多......:)
假设您使用的是最新版本的C#(3.5,我相信?),这可能是extension method的良好候选者。
答案 3 :(得分:1)
您是否考虑过向其中一个域类添加转换运算符以定义显式转换。 See the msdn documentation here.
享受!
答案 4 :(得分:1)
一种简单而快速的映射类型的方法是使用{strong> MiscUtil 库中的PropertyCopy<TTarget>.CopyFrom<TSource>(TSource source)
方法,如here所述:
using MiscUtil.Reflection;
class A
{
public int Foo { get; set; }
}
class B
{
public int Foo { get; set; }
}
class Program
{
static void Main()
{
A a = new A();
a.Foo = 17;
B b = PropertyCopy<B>.CopyFrom(a);
bool success = b.Foo == 17; // success is true;
}
}
答案 5 :(得分:0)
在两个不同的命名空间中具有完全相同签名的两个类是两个不同的类。如果它们没有明确说明如何使用隐式或显式运算符将它们从一个转换为另一个,则无法在它们之间进行隐式转换。
您可以使用序列化进行一些操作。一侧的WCF DataContract类不必与另一侧的DataContract完全相同;他们只需拥有相同的签名并进行相同的装饰。如果您的两个对象都是如此,则可以使用DataContractSerializer通过其DataContract修饰来“转换”类型。
如果您可以控制一个类或另一个类的实现,您还可以定义一个隐式或显式运算符,该运算符将定义如何将另一个类转换为您的类。这可能只是返回您的类型中另一个对象的深层副本的新引用。因为在这种情况下,我会将其定义为显式,以确保转换仅在您需要时执行(它将用于您明确转换的情况,例如myAppCustomer = (Appointment.CustomerParty)myCustCustomer;
)。
即使您不控制任何一个类,您也可以编写一个扩展方法或第三个类来执行此转换。