2个对象,完全相同(命名空间除外)c#

2个对象,完全相同(命名空间除外)c#,c#,namespaces,casting,C#,Namespaces,Casting,我正在使用第三方的一套Web服务,我遇到了一个小问题。在手动创建将每个属性从源复制到目标的方法之前,我想我应该在这里寻求更好的解决方案 我有两个对象,一个是Customer.CustomerParty类型,另一个是Appointment.CustomerParty类型。CustomerParty对象实际上是完全相同的属性和子项目。但我不能从1投到另一个 所以,我需要从网络服务中找到一个人。我可以通过调用Customer.FindCustomer(customerID)来实现这一点,它返回一个Cu

我正在使用第三方的一套Web服务,我遇到了一个小问题。在手动创建将每个属性从源复制到目标的方法之前,我想我应该在这里寻求更好的解决方案

我有两个对象,一个是Customer.CustomerParty类型,另一个是Appointment.CustomerParty类型。CustomerParty对象实际上是完全相同的属性和子项目。但我不能从1投到另一个

所以,我需要从网络服务中找到一个人。我可以通过调用Customer.FindCustomer(customerID)来实现这一点,它返回一个Customer.CustomerParty对象

我需要找到那个人,然后在“CreateAppointment”请求中使用他们几行。Appointment.CreateAppointment接受约会对象,约会对象包含CustomerParty对象

但是,它想要的CustomerParty对象实际上是appoint.CustomerParty。我有个顾客,顾客党


明白我的意思吗?有什么建议吗?

在编写域模式时,这种情况很常见。您基本上需要在两个对象之间编写一个域转换器。您可以通过几种方式实现这一点,但我建议在目标类型中使用一个重写构造函数(或静态方法),该构造函数接受服务类型并执行映射。因为它们是两种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;
    }
}

我使用的是第三方的 网络服务

假设您不能修改类,我不知道有什么方法可以更改强制转换行为。至少,没有比编写CustomerToAppointmentPartyTranslator()映射函数更复杂的了……:)

假设您使用的是C#(我相信是3.5?)的最新版本,这可能是一个很好的应用程序

为什么不使用?然后你可以做:

TheirCustomerPartyClass source = WebService.ItsPartyTime();

YourCustomerPartyClass converted = 
    Mapper.Map<TheirCustomerPartyClass, YourCustomerPartyClass>(source);

TheirCustomerPartyClass original = 
    Mapper.Map<YourCustomerPartyClass, TheirCustomerPartyClass>(converted);
theircstomerpartyclass source=WebService.ItsPartyTime();
您的CustomerPartyClass已转换=
Mapper.Map(源代码);
TheirCircostomerPartyClass原件=
Mapper.Map(已转换);
只要属性相同,就可以创建一个非常简单的贴图,如下所示:

Mapper.CreateMap<TheirCustomerPartyClass, YourCustomerPartyClass>();
Mapper.CreateMap<YourCustomerPartyClass, TheirCustomerPartyClass>();
Mapper.CreateMap();
CreateMap();

在两个不同的名称空间中,具有完全相同签名的两个类是两个不同的类。如果它们没有明确说明如何使用隐式或显式运算符将它们从一个转换为另一个,则无法在它们之间进行隐式转换

通过序列化,您可以做一些事情。一方的WCF DataContract类不必与另一方的DataContract类型完全相同;他们只需要有相同的签名和装饰相同。如果这对您的两个对象是正确的,那么您可以使用DataContractSerializer通过其DataContract装饰来“转换”类型

如果您可以控制一个类或另一个类的实现,还可以定义隐式或显式运算符,该运算符将定义如何将另一个类转换为您的类。这可能只是返回类型中其他对象的深度副本的新引用。由于是这种情况,我将其定义为显式,以确保仅在需要时执行转换(它将用于显式强制转换的情况,例如
myAppCustomer=(Appointment.CustomerParty)myCustCustomer;


即使您不控制任何一个类,也可以编写一个扩展方法或第三个类来执行此转换。

您是否考虑过向其中一个域类添加一个转换运算符来定义显式强制转换


享受吧

映射类型的一种简单而快速的方法是使用
PropertyCopy.CopyFrom(TSource-source)
库中的方法,如下所述:

使用MiscUtil.Reflection;
甲级
{
公共int Foo{get;set;}
}
B类
{
公共int Foo{get;set;}
}
班级计划
{
静态void Main()
{
A=新的A();
a、 Foo=17;
B=属性复制。复制自(a);
bool success=b.Foo==17;//成功是真的;
}
}

因为类来自不同的名称空间,这意味着它们与CLR的观点完全不同。这就是为什么你不能从一个转换到另一个。我会看看我们是否可以将这个添加到我们的项目中。不确定这是否值得在这一点上的开销,但谢谢你的建议。我相信这会解决我的问题。不幸的是,StackOverflow不会让我投票给你的帖子。OpenID在我的工作计算机上的StackOverflow上不起作用——其他OpenID站点可以,只是StackOverlow不起作用。@Matt-几乎没有开销。AutoMapper非常轻。绝对值得一试。对我来说效果很好。CreateMap();Entities.CorporateDelayTracking.Delay convertedDelay=Mapper.Map(Delay);我想我得走这条路(谢谢你的回答。不幸的是StackOverflow不允许我更新你的帖子。我的工作计算机上的StackOverflow不能使用OpenID——其他OpenID站点可以,只是不能使用StackOverlow。@Matt:你应该知道有一些简单的方法,比如动态方法,不需要你自己编写映射代码。你可以覆盖显式强制转换也是如此。@JordanParmer我认为这几乎是可能的最糟糕的解决方案。虽然在一个肤浅的情况下是可行的,一个类包含两个属性——正如您所展示的,它在任何更复杂的情况下都是绝对令人厌恶的(即“现实生活”)场景。@ver-您建议的备选方案是什么?我同意AutoMapper是一个不错的解决方案,但只有在属性保证相同的情况下,它才是简单的。当您将一个域连接到多个持久性源时,情况并不总是如此。我的方法(虽然简单)是明确的,几乎没有混淆的余地。
Mapper.CreateMap<TheirCustomerPartyClass, YourCustomerPartyClass>();
Mapper.CreateMap<YourCustomerPartyClass, TheirCustomerPartyClass>();
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;
    }
}