2 объекта, точно такие же (кроме пространства имен) С#
Я использую сторонний набор веб-сервисов, и я ударил небольшую загвоздка. Прежде чем я вручную сделаю метод, копирующий каждое свойство из источника в пункт назначения, я подумал, что попрошу здесь найти лучшее решение.
У меня есть 2 объекта, один из типов Customer.CustomerParty и один из типов Appointment.CustomerParty. Объекты CustomerParty на самом деле являются свойством и sub-oject точно так же. Но я не могу отбрасывать от 1 к другому.
Итак, мне нужно найти определенного человека из веб-службы. Я могу сделать это, вызвав Customer.FindCustomer(customerID), и он возвращает объект Customer.CustomerParty.
Мне нужно взять того человека, которого я нашел, а затем использовать несколько строк в запросе "CreateAppointment". Appointment.CreateAppointment принимает объект назначения, а объект назначения содержит объект CustomerParty.
Однако объект CustomerParty, который он хочет, действительно является Назначением. Клиентский пакет. У меня есть Customer.CustomerParty.
Посмотрите, что я имею в виду? Любые предложения?
Ответы
Ответ 1
Этот сценарий распространен при написании шаблонов доменов. Вам необходимо написать переводчик между двумя объектами. Вы можете сделать это несколькими способами, но я рекомендую иметь переопределенный конструктор (или статический метод) в целевом типе, который принимает тип сервиса и выполняет сопоставление. Поскольку они представляют собой два типа 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
Почему бы вам не использовать 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>();
Ответ 3
Я использую сторонний набор WebServices...
Предполагая, что вы не можете модифицировать классы, я не знаю, как вы можете изменить поведение каста. По крайней мере, далеко не так далеко, гораздо сложнее, чем просто написать функцию отображения CustomerToAppointmentPartyTranslator()...:)
Предполагая, что вы используете последнюю версию С# (3.5, я полагаю?), это может быть хорошим кандидатом для метода расширения ,
Ответ 4
Вы посмотрели на добавление оператора преобразования в один из классов домена для определения явного приведения. Смотрите здесь документацию msdn.
Наслаждайтесь!
Ответ 5
Простой и очень быстрый способ сопоставления типов использует метод PropertyCopy<TTarget>.CopyFrom<TSource>(TSource source)
из MiscUtil, как описано здесь:
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;
}
}
Ответ 6
Два класса с одинаковой сигнатурой в двух разных пространствах имен представляют собой два разных класса. Вы не сможете имплицитно конвертировать между ними, если они явно не указывают, как они могут быть преобразованы из одного в другое с помощью неявных или явных операторов.
Есть некоторые вещи, которые вы можете сделать с сериализацией. Классы WCF DataContract с одной стороны не обязательно должны быть того же типа, что и DataContract с другой стороны; они просто должны иметь одну и ту же подпись и оформляться одинаково. Если это верно для ваших двух объектов, вы можете использовать DataContractSerializer для "преобразования" типов через их декодирование DataContract.
Если у вас есть контроль над реализацией одного класса или другого, вы также можете определить неявный или явный оператор, который определит, как другой класс может быть преобразован в ваш. Это, вероятно, просто вернет новую ссылку на глубокую копию другого объекта в вашем типе. Поскольку это так, я бы определил его как явный, чтобы убедиться, что преобразование выполняется только тогда, когда вам НУЖНО (оно будет использоваться в случаях, когда вы явно выполняете, например myAppCustomer = (Appointment.CustomerParty)myCustCustomer;
).
Даже если вы не контролируете ни один класс, вы можете написать метод расширения или третий класс, который будет выполнять это преобразование.