HigLabo.Mapper(世界最速のC#のオブジェクトマッパー)

Higtyのシステムの作り方

現在の最新版 HigLabo.Mapper は .NET 9 をサポートしています。NuGetから利用可能です。

10年前(2015年)にILコードを用いた最初のオブジェクトマッパーを作成しました。2019年にExpression Tree を使って再実装し、大幅なパフォーマンス向上を達成しました。2025年時点でも「世界最速」をうたえるマッパーになっていると考えています。GitHubリポジトリは以下です。

https://github.com/higty/higlabo

NugetでHigLabo.Mapperと検索すると出てきます。


背景

近年、WebやDesktop、Mobileなどの開発においては、POCOやDTOといったクラス同士の値受け渡しが頻繁に必要になります。この作業を簡単にするのがオブジェクトマッパーです。今回の再実装で目標としたのは、以下の4点です。

  1. 世界最速
  2. 設定ゼロですぐに利用可能
  3. フルカスタマイズ により様々なユースケースに対応
  4. 複数のマッピングルール を同一アプリケーション内で管理かn


使い方

NuGetパッケージから HigLabo.Mapperを取得します。

アプリケーションに以下の using を追加してください:

using HigLabo.Core;

これにより、Map 拡張メソッドが使えます。たとえば:

var a1 = new Address(); // POCOクラス
var a2 = a1.Map(new Address());

Dictionary からクラスへのマッピングも可能です:

var d = new Dictionary<string, string>();
d["Name"] = "Bill";
var person = d.Map(new Person());
// person.Name は "Bill"

逆にクラスから Dictionary へのマッピングもできます:

var p = new Person();
p.Name = "Bill";
var d = p.Map(new Dictionary<string, string>());
// d["Name"] は "Bill"

このように HigLabo.Mapper は初期設定なしで使えるように設計されています。



他のマッパーとの比較

パフォーマンス

オブジェクトマッパーはループの深い箇所で繰り返し呼ばれやすいので、速度は非常に重要です。ベンチマークの結果、以下のような優位性がありました。

  1. AutoMapper より 3~4倍速い(コレクションを持たないPOCOの場合)
  2. Mapster より 10~20%速い(コレクションを持たないPOCOの場合)
  3. AgileMapper, FastMapper, TinyMapper より 7~10倍速い(コレクションを持たないPOCOの場合)
  4. AutoMapper より 3倍速い(コレクションを持つPOCOの場合)
  5. Mapster より 10倍速い(コレクションを持つPOCOの場合)
  6. AgileMapper, FastMapper, TinyMapper より 10~20倍速い(コレクションを持つPOCOの場合)


下記は BenchmarkDotNet を用いたテスト結果の一例で、HigLaboObjectMapper_XXXX が HigLabo.Mapper の計測値です。


比較に用いたクラス例は以下のとおりです。


public class Address
{
    public int Id { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public AddressType AddressType { get; set; }
}

public class AddressDTO
{
    public int Id { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public AddressType AddressType { get; set; } = AddressType.House;
}

public struct GpsPosition
{
    public double Latitude { get; private set; }
    public double Longitude { get; private set; }

    public GpsPosition(double latitude, double longitude)
    {
        Latitude = latitude;
        Longitude = longitude;
    }
}

public class Customer
{
    public Int32? Id { get; set; }
    public String Name { get; set; }
    public Address Address { get; set; }
    public Address HomeAddress { get; set; }
    public Address[] AddressList { get; set; }
    public IEnumerable<Address> WorkAddressList { get; set; }
}

public class CustomerDTO
{
    public Int32? Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
    public AddressDTO HomeAddress { get; set; }
    public AddressDTO[] AddressList { get; set; }
    public List<AddressDTO> WorkAddressList { get; set; }
    public String AddressCity { get; set; }
}
  1. さらに下記4パターンのマッピングを計測しています。
  2. コレクションを持たないPOCO同士 (Address -> Address)
  3. コレクションを持たないPOCOと別クラス (Address -> AddressDTO)
  4. コレクションを持つPOCO同士 (Customer -> Customer)
  5. コレクションを持つPOCOと別クラス (Customer -> CustomerDTO)


いずれのパターンでも HigLabo.Mapper が最速を記録しました。

詳細なテストコードは以下のGitHubで確認できます:

https://github.com/higty/higlabo/tree/master/Net9/HigLabo.Mapper.PerformanceTest


初期設定

一部のマッパーは初期設定として、以下のようにクラス同士のマッピングルールを明示的に書く必要があります。(AutoMapperやTinyMapperの例)

// AutoMapperの例
var configuration = new AutoMapper.MapperConfiguration(config => {
    config.CreateMap<Building, Building>();
    config.CreateMap<TreeNode, TreeNode>();
});

// TinyMapperの例
TinyMapper.Bind<Park, Park>();
TinyMapper.Bind<Customer, CustomerDTO>();
TinyMapper.Bind<Dictionary<String, String>, Building>();

大量のクラスがある場合、これらの設定は大きな負担です。

一方 HigLabo.Mapper は初期設定不要で使い始めることができます。


カスタマイズ

オブジェクトマッパーを使うと、「特定のプロパティ名を変換したい」「一部のケースでのみ別の処理を挟みたい」といった要望が出てきます。

AutoMapperではカスタマイズのためのメソッドや設定がやや複雑になることがありますが、HigLabo.Mapper では以下のように直感的に書けます。

// 後処理の例
c.AddPostAction<Source, Destination>((s, d) =>
{
    d.Id = s.Inner.Id;
    // Innerオブジェクトのプロパティを再度マッピング
    s.Inner.Map(d);
});

これはマッピング完了後に呼ばれるラムダを登録するだけです。複雑な設定方法を覚える必要はなく、C#のラムダに慣れていれば簡単に扱えます。

マッピング全体を置き換えることも可能です。

c.ReplaceMap<Source, Destination>((s, d) =>
{
    // 完全に自由にマッピングを書く
    d.Id = s.Inner.Id;
    s.Inner.Map(d);
});

// 実行時は
var source = new Source();
var destination = new Destination();
source.Map(destination); // 上記ルールで実行される

また、下記のように別メソッドで計算した値を割り当てる例も容易に書けます。

c.AddPostAction<Person, PersonVM>((s, d) =>
{
    d.BMI = CalculateBMI(s.Height, s.Weight);
});

条件付きの例も同様です。

c.AddPostAction<Employee, EmployeeVM>((s, d) =>
{
    if (s.EmployeeType == EmployeeType.Contract)
    {
        d.Property1 = someValue1;
    }
    else
    {
        d.Property1 = someValue2;
    }
});

デバッグ時にはこのラムダにブレークポイントを設定できるため、問題箇所を特定しやすいのもメリットです。

さらに、プロパティ名のマッチングルールを自由に設定することも可能です。

class Person
{
    public string Name { get; set; }
    public string Position_Name { get; set; }
}
class PersonModel
{
    public string Name { get; set; }
    public string PositionName { get; set; }
}

var mapper = HigLabo.Core.ObjectMapper.Default;
mapper.CompilerConfig.PropertyMatchRule =
    (sourceType, sourceProperty, targetType, targetProperty) =>
{
    if (sourceType == typeof(Person) && targetType == typeof(PersonModel))
    {
        // "Position_Name" -> "PositionName" のようにアンダースコアを除去
        return sourceProperty.Name.Replace("_", "") == targetProperty.Name;
    }
    return false;
};


複数設定の管理

HigLabo.Mapper は ObjectMapper クラスのインスタンスを複数作成できます。それぞれに固有のルールを持たせられるので、用途に応じた使い分けが可能です。

var om1 = new ObjectMapper();
om1.AddPostAction<Address, Address>((s, d) =>
{
    // ルール1
});

var om2 = new ObjectMapper();
om2.AddPostAction<Address, Address>((s, d) =>
{
    // ルール2
});

var a = new Address();
var a1 = om1.Map(a, new Address());
var a2 = om2.Map(a, new Address());

なお、Map拡張メソッドは内部で ObjectMapper.Default を呼び出しており、これは「標準的な1つのインスタンス」を使うための糖衣構文です。必要に応じて自分で新たなインスタンスを生成し、独自ルールを定義して使い分けることができます。


初期化処理をまとめて書く例も可能です。

public static class ObjectMapperExtensions
{
    public static void Initialize(this ObjectMapper mapper)
    {
        mapper.AddPostAction<Address, Address>((s, d) =>
        {
            // あなたのカスタムマッピング
        });
        mapper.AddPostAction<Address, Address>((s, d) =>
        {
            // 別のマッピング
        });
    }
}

// アプリケーション起動時など
ObjectMapper.Default.Initialize();


テストケース

ほぼすべてのテストケースは下記リポジトリで公開しています。

https://github.com/higty/higlabo/tree/master/Net9/HigLabo.Mapper.Test

以前のバージョンでサポートしていた機能は概ね検証済みですが、まだカバーしきれていない稀なケースもあるかもしれません。もし例外が出た場合は、Xでご連絡いただければ対応いたします。

https://x.com/higlabo


Deep Dive

内部でどのような式ツリーが生成されているか見てみましょう。例えばテストケース ObjectMapper_Map_ValueType_ValueType では、Vector2 -> Vector2 のマッピング用として以下のような式ツリー(Func<object, object, TTarget>)が生成されます。

.Lambda #Lambda1<System.Func`3[System.Object,System.Object,
                 HigLabo.Mapper.PerformanceTest.AddressDTO]>(
    System.Object $sourceParameter,
    System.Object $targetParameter) {
    .Block(
        HigLabo.Mapper.PerformanceTest.Address $source,
        HigLabo.Mapper.PerformanceTest.AddressDTO $target) {
        $source = $sourceParameter .As HigLabo.Mapper.PerformanceTest.Address;
        $target = $targetParameter .As HigLabo.Mapper.PerformanceTest.AddressDTO;
        .Call $target.set_Id($source.Id);
        .Call $target.set_City($source.City);
        .Call $target.set_Country($source.Country);
        .Call $target.set_AddressType($source.AddressType);
        $target
    }
}

Address -> AddressDTO の場合は下記のような式ツリーが出力されます。かなり長いですが全てを表示しておきます。

.Lambda #Lambda1<System.Func`3[System.Object,System.Object,HigLabo.Mapper.Test.User]>(
    System.Object $sourceParameter,
    System.Object $targetParameter) {
    .Block(
        HigLabo.Mapper.Test.User $source,
        HigLabo.Mapper.Test.User $target) {
        $source = $sourceParameter .As HigLabo.Mapper.Test.User;
        $target = $targetParameter .As HigLabo.Mapper.Test.User;
        .Call $target.set_Value($source.Value);
        .Call $target.set_Name($source.Name);
        .Call $target.set_Int32($source.Int32);
        .Call $target.set_Int32Nullable($source.Int32Nullable);
        .Call $target.set_Int32_Nullable($source.Int32_Nullable);
        .Call $target.set_Int32NullableToInt32($source.Int32NullableToInt32);
        .Call $target.set_DateTime($source.DateTime);
        .Call $target.set_DateTimeNullable($source.DateTimeNullable);
        .Call $target.set_Decimal($source.Decimal);
        .Call $target.set_DecimalNullable($source.DecimalNullable);
        .Call $target.set_DayOfWeek($source.DayOfWeek);
        .Call $target.set_DayOfWeekNullable($source.DayOfWeekNullable);
        .Call $target.set_Guid($source.Guid);
        .Call $target.set_GuidNullable($source.GuidNullable);
        .If ($source.MapPoint == null) {
            .Call $target.set_MapPoint(.Default(HigLabo.Mapper.Test.MapPoint))
        } .Else {
            .Block() {
                .If ($target.MapPoint == null) {
                    $target.MapPoint = .New HigLabo.Mapper.Test.MapPoint()
                } .Else {
                    .Default(System.Void)
                };
                .Call ($target.MapPoint).set_Longitude(($source.MapPoint).Longitude);
                .Call ($target.MapPoint).set_Latitude(($source.MapPoint).Latitude)
            }
        };
        .Call $target.set_VectorToNullable($source.VectorToNullable);
        .Call $target.set_Vector2($source.Vector2);
        .If ($source.ParentUser == null) {
            .Call $target.set_ParentUser(.Default(HigLabo.Mapper.Test.User))
        } .Else {
            .Block() {
                .If ($target.ParentUser == null) {
                    $target.ParentUser = .New HigLabo.Mapper.Test.User()
                } .Else {
                    .Default(System.Void)
                };
                .Call ($target.ParentUser)
                .set_Value(($source.ParentUser).Value);
                .Call ($target.ParentUser)
                .set_Name(($source.ParentUser).Name);
                .Call ($target.ParentUser)
                .set_Int32(($source.ParentUser).Int32);
                .Call ($target.ParentUser).set_Int32Nullable
                      (($source.ParentUser).Int32Nullable);
                .Call ($target.ParentUser).set_Int32_Nullable
                      (($source.ParentUser).Int32_Nullable);
                .Call ($target.ParentUser).set_Int32NullableToInt32
                      (($source.ParentUser).Int32NullableToInt32);
                .Call ($target.ParentUser)
                .set_DateTime(($source.ParentUser).DateTime);
                .Call ($target.ParentUser).set_DateTimeNullable
                      (($source.ParentUser).DateTimeNullable);
                .Call ($target.ParentUser)
                .set_Decimal(($source.ParentUser).Decimal);
                .Call ($target.ParentUser).set_DecimalNullable
                      (($source.ParentUser).DecimalNullable);
                .Call ($target.ParentUser).set_DayOfWeek
                      (($source.ParentUser).DayOfWeek);
                .Call ($target.ParentUser).set_DayOfWeekNullable
                      (($source.ParentUser).DayOfWeekNullable);
                .Call ($target.ParentUser)
                .set_Guid(($source.ParentUser).Guid);
                .Call ($target.ParentUser).set_GuidNullable
                      (($source.ParentUser).GuidNullable);
                .If (($source.ParentUser).MapPoint == null) {
                    .Call ($target.ParentUser).set_MapPoint
                          (.Default(HigLabo.Mapper.Test.MapPoint))
                } .Else {
                    .Block() {
                        .If (($target.ParentUser).MapPoint == null) {
                            ($target.ParentUser).MapPoint = 
                                    .New HigLabo.Mapper.Test.MapPoint()
                        } .Else {
                            .Default(System.Void)
                        };
                        .Call (($target.ParentUser).MapPoint).set_Longitude
                              ((($source.ParentUser).MapPoint).Longitude);
                        .Call (($target.ParentUser).MapPoint).set_Latitude
                              ((($source.ParentUser).MapPoint).Latitude)
                    }
                };
                .Call ($target.ParentUser).set_VectorToNullable
                      (($source.ParentUser).VectorToNullable);
                .Call ($target.ParentUser)
                .set_Vector2(($source.ParentUser).Vector2);
                .If (($source.ParentUser).ParentUser == null) {
                    .Call ($target.ParentUser).set_ParentUser
                          (.Default(HigLabo.Mapper.Test.User))
                } .Else {
                    .Block() {
                        .If (($target.ParentUser).ParentUser == null) {
                            ($target.ParentUser).ParentUser = 
                                    .New HigLabo.Mapper.Test.User()
                        } .Else {
                            .Default(System.Void)
                        };
                        .Call (($target.ParentUser).ParentUser).set_Value
                              ((($source.ParentUser).ParentUser).Value);
                        .Call (($target.ParentUser).ParentUser).set_Name
                              ((($source.ParentUser).ParentUser).Name);
                        .Call (($target.ParentUser).ParentUser).set_Int32
                              ((($source.ParentUser).ParentUser).Int32);
                        .Call (($target.ParentUser).ParentUser).set_Int32Nullable
                              ((($source.ParentUser).ParentUser).Int32Nullable);
                        .Call (($target.ParentUser).ParentUser).set_Int32_Nullable
                              ((($source.ParentUser).ParentUser).Int32_Nullable);
                        .Call (($target.ParentUser)
                        .ParentUser).set_Int32NullableToInt32
                              ((($source.ParentUser)
                              .ParentUser).Int32NullableToInt32);
                        .Call (($target.ParentUser).ParentUser).set_DateTime
                              ((($source.ParentUser).ParentUser).DateTime);
                        .Call (($target.ParentUser).ParentUser).set_DateTimeNullable
                              ((($source.ParentUser).ParentUser).DateTimeNullable);
                        .Call (($target.ParentUser).ParentUser).set_Decimal
                              ((($source.ParentUser).ParentUser).Decimal);
                        .Call (($target.ParentUser).ParentUser).set_DecimalNullable
                              ((($source.ParentUser).ParentUser).DecimalNullable);
                        .Call (($target.ParentUser).ParentUser).set_DayOfWeek
                              ((($source.ParentUser).ParentUser).DayOfWeek);
                        .Call (($target.ParentUser).ParentUser).set_DayOfWeekNullable
                              ((($source.ParentUser).ParentUser).DayOfWeekNullable);
                        .Call (($target.ParentUser).ParentUser).set_Guid
                              ((($source.ParentUser).ParentUser).Guid);
                        .Call (($target.ParentUser).ParentUser).set_GuidNullable
                              ((($source.ParentUser).ParentUser).GuidNullable);
                        .If ((($source.ParentUser).ParentUser).MapPoint == null) {
                            .Call (($target.ParentUser).ParentUser).set_MapPoint
                                  (.Default(HigLabo.Mapper.Test.MapPoint))
                        } .Else {
                            .Block() {
                                .If ((($target.ParentUser)
                                .ParentUser).MapPoint == null) {
                                    (($target.ParentUser).ParentUser).MapPoint = 
                                             .New HigLabo.Mapper.Test.MapPoint()
                                } .Else {
                                    .Default(System.Void)
                                };
                                .Call ((($target.ParentUser).ParentUser).MapPoint)
                                                            .set_Longitude
                                      (((($source.ParentUser).ParentUser).MapPoint)
                                                             .Longitude);
                                .Call ((($target.ParentUser).ParentUser).MapPoint)
                                                            .set_Latitude
                                      (((($source.ParentUser).ParentUser).MapPoint)
                                                             .Latitude)
                            }
                        };
                        .Call (($target.ParentUser).ParentUser).set_VectorToNullable
                              ((($source.ParentUser).ParentUser).VectorToNullable);
                        .Call (($target.ParentUser).ParentUser).set_Vector2
                              ((($source.ParentUser).ParentUser).Vector2);
                        .If ((($source.ParentUser).ParentUser).ParentUser == null) {
                            .Call (($target.ParentUser).ParentUser).set_ParentUser
                                  (.Default(HigLabo.Mapper.Test.User))
                        } .Else {
                            .Block() {
                                .If ((($target.ParentUser)
                                .ParentUser).ParentUser == null) {
                                    (($target.ParentUser).ParentUser).ParentUser = 
                                                         .New HigLabo.Mapper.Test.User()
                                } .Else {
                                    .Default(System.Void)
                                };
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Value
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Value);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Name
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Name);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Int32
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Int32);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Int32Nullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Int32Nullable);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Int32_Nullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Int32_Nullable);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Int32NullableToInt32
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Int32NullableToInt32);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_DateTime
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).DateTime);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_DateTimeNullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).DateTimeNullable);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Decimal
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Decimal);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_DecimalNullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).DecimalNullable);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_DayOfWeek
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).DayOfWeek);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_DayOfWeekNullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).DayOfWeekNullable);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Guid
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Guid);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_GuidNullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).GuidNullable);
                                .If (((($source.ParentUser).ParentUser)
                                .ParentUser).MapPoint == null) {
                                    .Call ((($target.ParentUser)
                                    .ParentUser).ParentUser).set_MapPoint
                                          (.Default(HigLabo.Mapper.Test.MapPoint))
                                } .Else {
                                    .Block() {
                                        .If (((($target.ParentUser).ParentUser)
                                        .ParentUser).MapPoint == null) {
                                            ((($target.ParentUser).ParentUser)
                                            .ParentUser).MapPoint = 
                                            .New HigLabo.Mapper.Test.MapPoint()
                                        } .Else {
                                            .Default(System.Void)
                                        };
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).MapPoint).set_Longitude
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).MapPoint).Longitude)
                                        ;
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).MapPoint).set_Latitude
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).MapPoint).Latitude)
                                    }
                                };
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_VectorToNullable
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).VectorToNullable);
                                .Call ((($target.ParentUser).ParentUser)
                                .ParentUser).set_Vector2
                                      (((($source.ParentUser).ParentUser)
                                      .ParentUser).Vector2);
                                .If (((($source.ParentUser).ParentUser)
                                .ParentUser).ParentUser == null) {
                                    .Call ((($target.ParentUser).ParentUser)
                                    .ParentUser).set_ParentUser
                                          (.Default(HigLabo.Mapper.Test.User))
                                } .Else {
                                    .Block() {
                                        .If (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser == null) {
                                            ((($target.ParentUser).ParentUser)
                                            .ParentUser).ParentUser = 
                                            .New HigLabo.Mapper.Test.User()
                                        } .Else {
                                            .Default(System.Void)
                                        };
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Value
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Value);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Name
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Name);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Int32
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Int32);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Int32Nullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Int32Nullable);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Int32_Nullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Int32_Nullable);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Int32NullableToInt32
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser)
                                              .Int32NullableToInt32);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_DateTime
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).DateTime);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_DateTimeNullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).DateTimeNullable);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Decimal
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Decimal);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_DecimalNullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).DecimalNullable);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_DayOfWeek
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).DayOfWeek);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_DayOfWeekNullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).DayOfWeekNullable);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Guid
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Guid);
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_GuidNullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).GuidNullable);
                                        .If ((((($source.ParentUser)
                                        .ParentUser).ParentUser)
                                        .ParentUser).MapPoint == null) {
                                            .Call (((($target.ParentUser).ParentUser)
                                            .ParentUser).ParentUser).set_MapPoint
                                                  (.Default(HigLabo.Mapper.Test.MapPoint))
                                        } .Else {
                                            .Block() {
                                                .If ((((($target.ParentUser).ParentUser)
                                                .ParentUser).ParentUser).MapPoint == null) {
                                                    (((($target.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).MapPoint = 
                                                        .New HigLabo.Mapper.Test.MapPoint()
                                                } .Else {
                                                    .Default(System.Void)
                                                }
                                            }
                                        };
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_VectorToNullable
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).VectorToNullable)
                                        ;
                                        .Call (((($target.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).set_Vector2
                                              ((((($source.ParentUser).ParentUser)
                                              .ParentUser).ParentUser).Vector2)
                                        ;
                                        .If ((((($source.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).ParentUser == null) {
                                            .Call (((($target.ParentUser).ParentUser)
                                            .ParentUser).ParentUser).set_ParentUser
                                                  (.Default(HigLabo.Mapper.Test.User))
                                        } .Else {
                                            .Block() {
                                                .If ((((($target.ParentUser).ParentUser)
                                                .ParentUser).ParentUser).ParentUser == null) {
                                                    (((($target.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).ParentUser = 
                                                        .New HigLabo.Mapper.Test.User()
                                                } .Else {
                                                    .Default(System.Void)
                                                }
                                            }
                                        };
                                        .If ((((($source.ParentUser).ParentUser)
                                        .ParentUser).ParentUser).Dictionary == null) {
                                            .Call (((($target.ParentUser).ParentUser)
                                            .ParentUser).ParentUser).set_Dictionary
                                               (.Default(System.Collections.Generic
                                               .Dictionary`2[System.String,System.String]))
                                        } .Else {
                                            .Block() {
                                                .If ((((($target.ParentUser).ParentUser)
                                                .ParentUser).ParentUser).Dictionary == null) {
                                                    (((($target.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Dictionary = 
                                                        .New System.Collections.Generic
                                               .Dictionary`2[System.String,System.String]()
                                                } .Else {
                                                    .Default(System.Void)
                                                }
                                            }
                                        }
                                    }
                                };
                                .If (((($source.ParentUser).ParentUser)
                                       .ParentUser).Dictionary == null) {
                                    .Call ((($target.ParentUser).ParentUser)
                                             .ParentUser).set_Dictionary
                                          (.Default(System.Collections.Generic.
                                            Dictionary`2[System.String,System.String]))
                                } .Else {
                                    .Block() {
                                        .If (((($target.ParentUser).ParentUser)
                                                .ParentUser).Dictionary == null) {
                                            ((($target.ParentUser).ParentUser)
                                            .ParentUser).Dictionary = 
                                               .New System.Collections.Generic.Dictionary`2
                                               [System.String,System.String]()
                                        } .Else {
                                            .Default(System.Void)
                                        }
                                    }
                                }
                            }
                        };
                        .If ((($source.ParentUser).ParentUser).Dictionary == null) {
                            .Call (($target.ParentUser).ParentUser).set_Dictionary
                                  (.Default(System.Collections.Generic.Dictionary`2
                                           [System.String,System.String]))
                        } .Else {
                            .Block() {
                                .If ((($target.ParentUser).ParentUser).Dictionary == null) {
                                    (($target.ParentUser).ParentUser).Dictionary = 
                                     .New System.Collections.Generic.Dictionary`2
                                          [System.String,System.String]()
                                } .Else {
                                    .Default(System.Void)
                                }
                            }
                        }
                    }
                };
                .If (($source.ParentUser).Dictionary == null) {
                    .Call ($target.ParentUser).set_Dictionary
                          (.Default(System.Collections.Generic.Dictionary`2
                                   [System.String,System.String]))
                } .Else {
                    .Block() {
                        .If (($target.ParentUser).Dictionary == null) {
                            ($target.ParentUser).Dictionary = 
                             .New System.Collections.Generic.Dictionary`2
                                  [System.String,System.String]()
                        } .Else {
                            .Default(System.Void)
                        }
                    }
                }
            }
        };
        .If ($source.Dictionary == null) {
            .Call $target.set_Dictionary(.Default
            (System.Collections.Generic.Dictionary`2[System.String,System.String]))
        } .Else {
            .Block() {
                .If ($target.Dictionary == null) {
                    $target.Dictionary = .New System.Collections.Generic.Dictionary`2
                                         [System.String,System.String]()
                } .Else {
                    .Default(System.Void)
                }
            }
        };
        .If ($target.Users == null) {
            .Call $target.set_Users(.New System.Collections.Generic.List`1
                                   [HigLabo.Mapper.Test.User]())
        } .Else {
            .Default(System.Void)
        };
        .Block(
            HigLabo.Mapper.Test.User $sourceElement,
            HigLabo.Mapper.Test.User $targetElement,
            System.Int32 $i) {
            $i;
            .If ($source.Users == null) {
                .Return end { }
            } .Else {
                .Default(System.Void)
            };
            $i = 0;
            .Loop  {
                .Block() {
                    .If (($source.Users).Count <= $i) {
                        .Break endLoop { }
                    } .Else {
                        .Default(System.Void)
                    };
                    $sourceElement = ($source.Users).Item[$i];
                    $targetElement = .New HigLabo.Mapper.Test.User();
                    .Call $targetElement.set_Value($sourceElement.Value);
                    .Call $targetElement.set_Name($sourceElement.Name);
                    .Call $targetElement.set_Int32($sourceElement.Int32);
                    .Call $targetElement.set_Int32Nullable($sourceElement.Int32Nullable);
                    .Call $targetElement.set_Int32_Nullable($sourceElement.Int32_Nullable);
                    .Call $targetElement.set_Int32NullableToInt32
                                         ($sourceElement.Int32NullableToInt32);
                    .Call $targetElement.set_DateTime($sourceElement.DateTime);
                    .Call $targetElement.set_DateTimeNullable
                                         ($sourceElement.DateTimeNullable);
                    .Call $targetElement.set_Decimal($sourceElement.Decimal);
                    .Call $targetElement.set_DecimalNullable
                                         ($sourceElement.DecimalNullable);
                    .Call $targetElement.set_DayOfWeek($sourceElement.DayOfWeek);
                    .Call $targetElement.set_DayOfWeekNullable
                                         ($sourceElement.DayOfWeekNullable);
                    .Call $targetElement.set_Guid($sourceElement.Guid);
                    .Call $targetElement.set_GuidNullable($sourceElement.GuidNullable);
                    .If ($sourceElement.MapPoint == null) {
                        .Call $targetElement.set_MapPoint(.Default
                                             (HigLabo.Mapper.Test.MapPoint))
                    } .Else {
                        .Block() {
                            .If ($targetElement.MapPoint == null) {
                                $targetElement.MapPoint = 
                                   .New HigLabo.Mapper.Test.MapPoint()
                            } .Else {
                                .Default(System.Void)
                            };
                            .Call ($targetElement.MapPoint).set_Longitude
                                  (($sourceElement.MapPoint).Longitude);
                            .Call ($targetElement.MapPoint).set_Latitude
                                  (($sourceElement.MapPoint).Latitude)
                        }
                    };
                    .Call $targetElement.set_VectorToNullabl
                          e($sourceElement.VectorToNullable);
                    .Call $targetElement.set_Vector2($sourceElement.Vector2);
                    .If ($sourceElement.ParentUser == null) {
                        .Call $targetElement.set_ParentUser
                              (.Default(HigLabo.Mapper.Test.User))
                    } .Else {
                        .Block() {
                            .If ($targetElement.ParentUser == null) {
                                $targetElement.ParentUser = 
                                   .New HigLabo.Mapper.Test.User()
                            } .Else {
                                .Default(System.Void)
                            };
                            .Call ($targetElement.ParentUser).set_Value
                                  (($sourceElement.ParentUser).Value);
                            .Call ($targetElement.ParentUser).set_Name
                                  (($sourceElement.ParentUser).Name);
                            .Call ($targetElement.ParentUser).set_Int32
                                  (($sourceElement.ParentUser).Int32);
                            .Call ($targetElement.ParentUser).set_Int32Nullable
                                  (($sourceElement.ParentUser).Int32Nullable);
                            .Call ($targetElement.ParentUser).set_Int32_Nullable
                                  (($sourceElement.ParentUser).Int32_Nullable);
                            .Call ($targetElement.ParentUser).set_Int32NullableToInt32
                                  (($sourceElement.ParentUser).Int32NullableToInt32);
                            .Call ($targetElement.ParentUser).set_DateTime
                                  (($sourceElement.ParentUser).DateTime);
                            .Call ($targetElement.ParentUser).set_DateTimeNullable
                                  (($sourceElement.ParentUser).DateTimeNullable);
                            .Call ($targetElement.ParentUser).set_Decimal
                                  (($sourceElement.ParentUser).Decimal);
                            .Call ($targetElement.ParentUser).set_DecimalNullable
                                  (($sourceElement.ParentUser).DecimalNullable);
                            .Call ($targetElement.ParentUser).set_DayOfWeek
                                  (($sourceElement.ParentUser).DayOfWeek);
                            .Call ($targetElement.ParentUser).set_DayOfWeekNullable
                                  (($sourceElement.ParentUser).DayOfWeekNullable);
                            .Call ($targetElement.ParentUser).set_Guid
                                  (($sourceElement.ParentUser).Guid);
                            .Call ($targetElement.ParentUser).set_GuidNullable
                                  (($sourceElement.ParentUser).GuidNullable);
                            .If (($sourceElement.ParentUser).MapPoint == null) {
                                .Call ($targetElement.ParentUser).set_MapPoint
                                      (.Default(HigLabo.Mapper.Test.MapPoint))
                            } .Else {
                                .Block() {
                                    .If (($targetElement.ParentUser).MapPoint == null) {
                                        ($targetElement.ParentUser).MapPoint = 
                                          .New HigLabo.Mapper.Test.MapPoint()
                                    } .Else {
                                        .Default(System.Void)
                                    };
                                    .Call (($targetElement.ParentUser).MapPoint).set_Longitude
                                          ((($sourceElement.ParentUser).MapPoint).Longitude);
                                    .Call (($targetElement.ParentUser).MapPoint).set_Latitude
                                          ((($sourceElement.ParentUser).MapPoint).Latitude)
                                }
                            };
                            .Call ($targetElement.ParentUser).set_VectorToNullable
                                  (($sourceElement.ParentUser).VectorToNullable);
                            .Call ($targetElement.ParentUser).set_Vector2
                                  (($sourceElement.ParentUser).Vector2);
                            .If (($sourceElement.ParentUser).ParentUser == null) {
                                .Call ($targetElement.ParentUser).set_ParentUser
                                      (.Default(HigLabo.Mapper.Test.User))
                            } .Else {
                                .Block() {
                                    .If (($targetElement.ParentUser).ParentUser == null) {
                                        ($targetElement.ParentUser).ParentUser = 
                                                     .New HigLabo.Mapper.Test.User()
                                    } .Else {
                                        .Default(System.Void)
                                    };
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Value
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Value);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Name
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Name);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Int32
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Int32);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Int32Nullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Int32Nullable);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Int32_Nullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Int32_Nullable);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Int32NullableToInt32
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Int32NullableToInt32);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_DateTime
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).DateTime);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_DateTimeNullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).DateTimeNullable);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Decimal
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Decimal);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_DecimalNullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).DecimalNullable);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_DayOfWeek
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).DayOfWeek);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_DayOfWeekNullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).DayOfWeekNullable);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Guid
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Guid);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_GuidNullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).GuidNullable);
                                    .If ((($sourceElement.ParentUser)
                                    .ParentUser).MapPoint == null) {
                                        .Call (($targetElement.ParentUser)
                                        .ParentUser).set_MapPoint
                                              (.Default(HigLabo.Mapper.Test.MapPoint))
                                    } .Else {
                                        .Block() {
                                            .If ((($targetElement.ParentUser)
                                            .ParentUser).MapPoint == null) {
                                                (($targetElement.ParentUser)
                                                .ParentUser).MapPoint = 
                                                .New HigLabo.Mapper.Test.MapPoint()
                                            } .Else {
                                                .Default(System.Void)
                                            };
                                            .Call ((($targetElement.ParentUser)
                                                  .ParentUser).MapPoint).set_Longitude
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).MapPoint).Longitude);
                                            .Call ((($targetElement.ParentUser)
                                                  .ParentUser).MapPoint).set_Latitude
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).MapPoint).Latitude)
                                        }
                                    };
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_VectorToNullable
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).VectorToNullable);
                                    .Call (($targetElement.ParentUser)
                                    .ParentUser).set_Vector2
                                          ((($sourceElement.ParentUser)
                                          .ParentUser).Vector2);
                                    .If ((($sourceElement.ParentUser)
                                    .ParentUser).ParentUser == null) {
                                        .Call (($targetElement.ParentUser).ParentUser)
                                        .set_ParentUser(.Default(HigLabo.Mapper.Test.User))
                                    } .Else {
                                        .Block() {
                                            .If ((($targetElement.ParentUser).ParentUser)
                                            .ParentUser == null) {
                                                (($targetElement.ParentUser).ParentUser)
                                                .ParentUser = .New HigLabo.Mapper.Test.User()
                                            } .Else {
                                                .Default(System.Void)
                                            };
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Value
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Value);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Name
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Name);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Int32
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Int32);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Int32Nullable
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Int32Nullable);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Int32_Nullable
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Int32_Nullable);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser)
                                            .set_Int32NullableToInt32
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser)
                                                  .Int32NullableToInt32);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_DateTime
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).DateTime);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_DateTimeNullable
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser)
                                                  .DateTimeNullable);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Decimal
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Decimal);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_DecimalNullable
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser)
                                                  .DecimalNullable);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_DayOfWeek
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).DayOfWeek);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_DayOfWeekNullable
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser)
                                                  .DayOfWeekNullable);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_Guid
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).Guid);
                                            .Call ((($targetElement.ParentUser)
                                            .ParentUser).ParentUser).set_GuidNullable
                                                  (((($sourceElement.ParentUser)
                                                  .ParentUser).ParentUser).GuidNullable);
                                            .If (((($sourceElement.ParentUser)
                                            .ParentUser).ParentUser).MapPoint == null) {
                                                .Call ((($targetElement.ParentUser)
                                                .ParentUser).ParentUser).set_MapPoint
                                                (.Default(HigLabo.Mapper.Test.MapPoint))
                                            } .Else {
                                                .Block() {
                                                    .If (((($targetElement.ParentUser)
                                                    .ParentUser).ParentUser).MapPoint == null) {
                                                        ((($targetElement.ParentUser)
                                                        .ParentUser).ParentUser).MapPoint = 
                                                        .New HigLabo.Mapper.Test.MapPoint()
                                                    } .Else {
                                                        .Default(System.Void)
                                                    };
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser).ParentUser)
                                                    .MapPoint).set_Longitude
                                                          ((((($sourceElement.ParentUser)
                                                          .ParentUser).ParentUser)
                                                          .MapPoint).Longitude);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser).ParentUser)
                                                    .MapPoint).set_Latitude
                                                          ((((($sourceElement.ParentUser)
                                                          .ParentUser).ParentUser)
                                                          .MapPoint).Latitude)
                                                }
                                            };
                                            .Call ((($targetElement.ParentUser).ParentUser)
                                            .ParentUser).set_VectorToNullable
                                                  (((($sourceElement.ParentUser).ParentUser)
                                                  .ParentUser).VectorToNullable);
                                            .Call ((($targetElement.ParentUser).ParentUser)
                                            .ParentUser).set_Vector2
                                                  (((($sourceElement.ParentUser).ParentUser)
                                                  .ParentUser).Vector2);
                                            .If (((($sourceElement.ParentUser).ParentUser)
                                            .ParentUser).ParentUser == null) {
                                                .Call ((($targetElement.ParentUser).ParentUser)
                                                .ParentUser).set_ParentUser
                                                      (.Default(HigLabo.Mapper.Test.User))
                                            } .Else {
                                                .Block() {
                                                    .If (((($targetElement.ParentUser)
                                                    .ParentUser).ParentUser).ParentUser == null) {
                                                        ((($targetElement.ParentUser)
                                                        .ParentUser).ParentUser).ParentUser = 
                                                        .New HigLabo.Mapper.Test.User()
                                                    } .Else {
                                                        .Default(System.Void)
                                                    };
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Value
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Value);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Name
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Name);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Int32
                                                    ((((($sourceElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).Int32);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Int32Nullable
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Int32Nullable);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Int32_Nullable
                                                    ((((($sourceElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).Int32_Nullable);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser)
                                                    .set_Int32NullableToInt32
                                                    ((((($sourceElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser)
                                                    .Int32NullableToInt32);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_DateTime
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).DateTime);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_DateTimeNullable
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).DateTimeNullable);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Decimal
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Decimal);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_DecimalNullable
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).DecimalNullable);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_DayOfWeek
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).DayOfWeek);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_DayOfWeekNullable
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).DayOfWeekNullable);
                                                    .Call (((($targetElement.ParentUser)
                                                    .ParentUser)
                                                    .ParentUser).ParentUser).set_Guid
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Guid);
                                                    .Call (((($targetElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).set_GuidNullable
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).GuidNullable);
                                                    .If ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).MapPoint == null) {
                                                        .Call (((($targetElement.ParentUser)
                                                        .ParentUser)
                                                        .ParentUser).ParentUser).set_MapPoint
                                                        (.Default(HigLabo.Mapper.Test.MapPoint))
                                                    } .Else {
                                                        .Block() {
                                                            .If ((((($targetElement.ParentUser)
                                                            .ParentUser)
                                                            .ParentUser).ParentUser).MapPoint == null) {
                                                                (((($targetElement.ParentUser)
                                                                .ParentUser)
                                                                .ParentUser).ParentUser).MapPoint = 
                                                                .New HigLabo.Mapper.Test.MapPoint()
                                                            } .Else {
                                                                .Default(System.Void)
                                                            }
                                                        }
                                                    };
                                                    .Call (((($targetElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).set_VectorToNullable
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).VectorToNullable);
                                                    .Call (((($targetElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).set_Vector2
                                                    ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).Vector2);
                                                    .If ((((($sourceElement.ParentUser).ParentUser)
                                                    .ParentUser).ParentUser).ParentUser == null) {
                                                        .Call (((($targetElement.ParentUser)
                                                        .ParentUser)
                                                        .ParentUser).ParentUser).set_ParentUser
                                                              (.Default(HigLabo.Mapper.Test.User))
                                                    } .Else {
                                                        .Block() {
                                                            .If ((((($targetElement.ParentUser)
                                                            .ParentUser)
                                                            .ParentUser).ParentUser).ParentUser == null) {
                                                                (((($targetElement.ParentUser)
                                                                .ParentUser)
                                                                .ParentUser).ParentUser).ParentUser = 
                                                                .New HigLabo.Mapper.Test.User()
                                                            } .Else {
                                                                .Default(System.Void)
                                                            }
                                                        }
                                                    };
                                                    .If ((((($sourceElement.ParentUser)
                                                        .ParentUser).ParentUser)
                                                        .ParentUser).Dictionary == null) {
                                                        .Call (((($targetElement.ParentUser)
                                                        .ParentUser)
                                                        .ParentUser).ParentUser).set_Dictionary
                                                        (.Default(System.Collections
                                                        .Generic.Dictionary`2
                                                        [System.String,System.String]))
                                                    } .Else {
                                                        .Block() {
                                                            .If ((((($targetElement.ParentUser)
                                                            .ParentUser)
                                                            .ParentUser).ParentUser).Dictionary == null) {
                                                                (((($targetElement.ParentUser)
                                                                .ParentUser)
                                                                .ParentUser).ParentUser).Dictionary = 
                                                                .New System.Collections
                                                                .Generic.Dictionary`2
                                                                [System.String,System.String]()
                                                            } .Else {
                                                                .Default(System.Void)
                                                            }
                                                        }
                                                    }
                                                }
                                            };
                                            .If (((($sourceElement.ParentUser).ParentUser)
                                                   .ParentUser).Dictionary == null) {
                                                .Call ((($targetElement.ParentUser).ParentUser)
                                                .ParentUser).set_Dictionary(.Default
                                                      (System.Collections.Generic.Dictionary`2
                                                      [System.String,System.String]))
                                            } .Else {
                                                .Block() {
                                                    .If (((($targetElement.ParentUser)
                                                        .ParentUser).ParentUser)
                                                        .Dictionary == null) {
                                                        ((($targetElement.ParentUser).ParentUser)
                                                        .ParentUser).Dictionary = 
                                                          .New System.Collections.Generic
                                                          .Dictionary`2[System.String,
                                                           System.String]()
                                                    } .Else {
                                                        .Default(System.Void)
                                                    }
                                                }
                                            }
                                        }
                                    };
                                    .If ((($sourceElement.ParentUser).ParentUser)
                                        .Dictionary == null) {
                                        .Call (($targetElement.ParentUser).ParentUser)
                                        .set_Dictionary(.Default
                                        (System.Collections.Generic.Dictionary`2
                                        [System.String,System.String]))
                                    } .Else {
                                        .Block() {
                                            .If ((($targetElement.ParentUser).ParentUser)
                                                .Dictionary == null) {
                                                (($targetElement.ParentUser).ParentUser)
                                                .Dictionary = 
                                                .New System.Collections.Generic.Dictionary`2
                                                [System.String,System.String]()
                                            } .Else {
                                                .Default(System.Void)
                                            }
                                        }
                                    }
                                }
                            };
                            .If (($sourceElement.ParentUser).Dictionary == null) {
                                .Call ($targetElement.ParentUser).set_Dictionary
                                (.Default(System.Collections.Generic.Dictionary`2
                                [System.String,System.String]))
                            } .Else {
                                .Block() {
                                    .If (($targetElement.ParentUser).Dictionary == null) {
                                        ($targetElement.ParentUser).Dictionary = 
                                        .New System.Collections.Generic.Dictionary`2
                                        [System.String,System.String]()
                                    } .Else {
                                        .Default(System.Void)
                                    }
                                }
                            }
                        }
                    };
                    .If ($sourceElement.Dictionary == null) {
                        .Call $targetElement.set_Dictionary(.Default
                        (System.Collections.Generic.Dictionary`2
                        [System.String,System.String]))
                    } .Else {
                        .Block() {
                            .If ($targetElement.Dictionary == null) {
                                $targetElement.Dictionary = 
                                .New System.Collections.Generic.Dictionary`2
                                [System.String,System.String]()
                            } .Else {
                                .Default(System.Void)
                            }
                        }
                    };
                    .Call ($target.Users).Add($targetElement);
                    $i += 1
                }
            }
            .LabelTarget endLoop:;
            .Label
            .LabelTarget end:
        };
        .Block(
            System.Guid $sourceElement,
            System.Guid $targetElement,
            System.Int32 $i) {
            $i;
            .If ($source.GuidList == null) {
                .Return end { }
            } .Else {
                .Default(System.Void)
            };
            $i = 0;
            .Loop  {
                .Block() {
                    .If (($source.GuidList).Count <= $i) {
                        .Break endLoop { }
                    } .Else {
                        .Default(System.Void)
                    };
                    $sourceElement = ($source.GuidList).Item[$i];
                    $targetElement = (System.Guid)$sourceElement;
                    .Call ($target.GuidList).Add($targetElement);
                    $i += 1
                }
            }
            .LabelTarget endLoop:;
            .Label
            .LabelTarget end:
        };
        .If ($source.Tags != null) {
            .Block(
                System.String $sourceElement,
                System.String $targetElement,
                System.Int32 $i,
                System.String[] $arrayMember) {
                $i;
                $i = 0;
                $arrayMember;
                $arrayMember = .NewArray System.String[($source.Tags).Length];
                .Loop  {
                    .Block() {
                        .If (($source.Tags).Length <= $i) {
                            .Break endLoop { }
                        } .Else {
                            .Default(System.Void)
                        };
                        $sourceElement = ($source.Tags)[$i];
                        $targetElement = $sourceElement;
                        $arrayMember[$i] = $targetElement;
                        $i += 1
                    }
                }
                .LabelTarget endLoop:;
                $target.Tags = $arrayMember
            }
        } .Else {
            .Default(System.Void)
        };
        .If ($source.Timestamp != null) {
            .Block(
                System.Byte $sourceElement,
                System.Byte $targetElement,
                System.Int32 $i,
                System.Byte[] $arrayMember) {
                $i;
                $i = 0;
                $arrayMember;
                $arrayMember = .NewArray System.Byte[($source.Timestamp).Length];
                .Loop  {
                    .Block() {
                        .If (($source.Timestamp).Length <= $i) {
                            .Break endLoop { }
                        } .Else {
                            .Default(System.Void)
                        };
                        $sourceElement = ($source.Timestamp)[$i];
                        $targetElement = $sourceElement;
                        $arrayMember[$i] = $targetElement;
                        $i += 1
                    }
                }
                .LabelTarget endLoop:;
                $target.Timestamp = $arrayMember
            }
        } .Else {
            .Default(System.Void)
        };
        $target
    }
}

コレクションを含むクラスに対しては、分岐やループを含むさらに大きな式ツリーが生成されますが、基本原理は同じです。

これらの式ツリーは初回の呼び出し時のみコンパイルされ、後はキャッシュされた Func を使うため2回目以降は高速にマッピングできます。


まとめ

HigLabo.Mapper が、オブジェクト間のマッピングをシンプルにし、生産性向上に役立つライブラリとなれば幸いです。