13


4

2つのオブジェクト、まったく同じ(名前空間を除く)c#

サードパーティの一連のWebサービスを使用していますが、小さな障害が発生しました。 ソースからデスティネーションに各プロパティをコピーするメソッドを手動で作成する前に、ここでより良い解決策を求めたいと思いました。

Customer.CustomerParty型とAppointment.CustomerParty型の2つのオブジェクトがあります。 CustomerPartyオブジェクトは実際にはプロパティであり、サブオブジェクトはまったく同じです。 しかし、1から他にキャストすることはできません。

そのため、Webサービスから特定の人を見つける必要があります。 Customer.FindCustomer(customerID)を呼び出すことでそれを行うことができ、Customer.CustomerPartyオブジェクトを返します。

見つけた人を「CreateAppointment」リクエストで数行使用する必要があります。 Appointment.CreateAppointmentは予定オブジェクトを受け取り、予定オブジェクトにはCustomerPartyオブジェクトが含まれます。

ただし、必要なCustomerPartyオブジェクトは実際にはAppointment.CustomerPartyです。 Customer.CustomerPartyがあります。

私の言っていることがわかりますか? 助言がありますか?

6 Answer


12


なぜhttp://automapper.codeplex.com/[AutoMapper]を使用しないのですか? それからあなたはすることができます:

TheirCustomerPartyClass source = WebService.ItsPartyTime();

YourCustomerPartyClass converted =
    Mapper.Map(source);

TheirCustomerPartyClass original =
    Mapper.Map(converted);

プロパティが同一である限り、次のような本当にシンプルなマップを作成できます。

Mapper.CreateMap();
Mapper.CreateMap();


7


このシナリオは、ドメインパターンを記述する場合に一般的です。 基本的に、2つのオブジェクト間にドメイントランスレーターを作成する必要があります。 これはいくつかの方法で実行できますが、サービスタイプを取得してマッピングを実行するターゲットタイプでオーバーライドされたコンストラクター(または静的メソッド)を使用することをお勧めします。 これらは2つの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;
    }
}

Or

public static class DomainTranslator
{
    public static ServiceType Translate( ClientType type )
    {
        return new ServiceType { FieldOne = type.FieldOne, FieldTwo = type.FieldTwo };
    }
}


1


_ サードパーティの一連のウェブサービスを使用しています…​ _

クラスを変更できないと仮定すると、キャスト動作を変更できる方法はわかりません。 少なくとも、CustomerToAppointmentPartyTranslator()マッピング関数を記述することほど遠くない、はるかに複雑な方法はありません…​ :)

C#の最新バージョン(3.5、私は信じますか?)を使用していると仮定すると、これはhttp://msdn.microsoft.com/en-us/library/bb383977.aspx[extension method]の良い候補かもしれません。


1


ドメインクラスの1つに*変換演算子*を追加して、明示的なキャストを定義することを検討しましたか。 msdnのドキュメントを参照してください。

楽しい!


1


型をマッピングするシンプルで非常に高速な方法は、httpsで説明されているように* http://www.yoda.arachsys.com/csharp/miscutil/ [MiscUtil] *ライブラリの `PropertyCopy.CopyFrom(TSource source)`メソッドを使用することです://stackoverflow.com/questions/852064/faster-deep-cloning/852094#852094 [こちら]:

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.CopyFrom(a);

        bool success = b.Foo == 17; // success is true;
    }
}


0


2つの異なる名前空間にあるまったく同じ署名を持つ2つのクラスは、2つの異なるクラスです。 暗黙的または明示的な演算子を使用して一方から他方への変換方法を明示的に指定していない場合、それらの間で暗黙的に変換することはできません。

シリアル化でできることはいくつかあります。 一方のWCF DataContractクラスは、他方のDataContractとまったく同じタイプである必要はありません。それらは同じ署名を持ち、同じように装飾されている必要があります。 これが2つのオブジェクトに当てはまる場合、DataContractSerializerを使用して、DataContract装飾を介して型を「変換」できます。

あるクラスまたは他のクラスの実装を制御できる場合は、他のクラスを自分のクラスに変換する方法を定義する暗黙的または明示的な演算子を定義することもできます。 これはおそらく、型内の他のオブジェクトのディープコピーの新しい参照を返すだけです。 これがそうであるため、変換が必要なときにのみ実行されるように明示的に定義します( `myAppCustomer =(Appointment.CustomerParty)myCustCustomer;`など、明示的にキャストする場合に使用されます) )。

どちらのクラスも制御しない場合でも、この変換を実行する拡張メソッドまたは3番目のクラスを作成できます。