2013-07-16 7 views
8

2つの異なるオブジェクトのフィールドをマップし、そのオブジェクトに値を割り当てる方法を知りたい。2つの異なるオブジェクトのプロパティをマップするにはどうすればよいですか?

Eample:

public class employee 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 

public class manager 
{ 
    public int MgrId { get; set; } 
    public string MgrName { get; set; } 
} 

今私はListオブジェクトを持っています。私は値を "マネージャ"クラスに割り当てたいと思う。それを行うための自動方法。私はそれを明示的に行い、それに値を割り当てることができます。しかし、私のオブジェクトは非常に巨大な問題です。私は、サードパーティのツールも使いたくない。

注:管理者のプレフィックスは使用できません。それは何でもかまいません。 (例:mgrIdはmgrCodeのようにすることができます)

+4

*「私も任意のサードパーティ製のツールを使用したくありません。 "* 何故なの? –

+2

反射を使用http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx –

+5

ちょうど提案:http://automapper.org/、このようなオブジェクトを変換するための素晴らしいツールです。 –

答えて

14

あなたは(employee.IDmanager.MgrIdに気づく)でも、プロパティケーシングを無視して、それのためにリフレクションを使用することができます。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var employee = new Employee() { ID = 1, Name = "John" }; 
     var manager = new Manager(); 
     foreach (PropertyInfo propertyInfo in typeof(Employee).GetProperties()) 
     { 
      typeof(Manager) 
       .GetProperty("Mgr" + propertyInfo.Name, 
        BindingFlags.IgnoreCase | 
        BindingFlags.Instance | 
        BindingFlags.Public) 
       .SetValue(manager, 
        propertyInfo.GetValue(employee)); 
     } 
    } 
} 

public class Employee 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 

public class Manager 
{ 
    public int MgrId { get; set; } 
    public string MgrName { get; set; } 
} 

あなたがMgr接頭語がわからない場合、あなただけの一致する可能性

foreach (PropertyInfo propertyInfo in typeof(Employee).GetProperties()) 
{ 
    typeof(Manager).GetMembers() 
     .OfType<PropertyInfo>() 
     .FirstOrDefault(p => p.Name.EndsWith(propertyInfo.Name, 
      StringComparison.CurrentCultureIgnoreCase)) 
     .SetValue(manager, 
      propertyInfo.GetValue(employee)); 
} 

そして非常に狭く、非現実的な仮定:マッピングB接尾辞によって、 (2つの型が同じ順序と数で定義されたプロパティを持つことを期待している場合、唯一の違いはプロパティ名です)。私は実際の生活の中でそれを使用して誰にもお勧めしませんが、それでも、ここにある(ただ作るために、それより壊れやすい :)):

typeof(Employee) 
    .GetProperties() 
    .Select((p, index) => 
     new { Index = index, PropertyInfo = p }) 
    .ToList() 
    .ForEach(p => 
     { 
      typeof(Manager) 
       .GetProperties() 
       .Skip(p.Index) 
       .FirstOrDefault() 
       .SetValue(manager, 
        p.PropertyInfo.GetValue(employee)); 
     }); 
+1

ソースオブジェクトを取得する['PropertyInfo.GetValue'](http://msdn.microsoft.com/en-us/library/hh194385.aspx)のオーバーロードがあります。 ['PropertyInfo.SetValue'](http://msdn.microsoft.com/en-us/library/hh194291.aspx)の2つの引数のオーバーロードもあります。 – Romoku

+0

修正は4.5から始まります。私は3.5とコンパイルしていた:)私は私の答えを更新します。 –

+0

最近、私は.Net 4.5をたくさん使ってきたと思います。 – Romoku

10

反射またはAutoMapperを使用します。私は後者をお勧めします。なぜなら、新しいコードを書くことは、目的がなければ無駄です。

public class Employee 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class Manager 
{ 
    public int MgrId { get; set; } 
    public string MgrName { get; set; } 
} 

Mapper.Initialize(cfg => 
{ 
    cfg.RecognizeDestinationPrefixes("Mgr"); 
    cfg.CreateMap<Employee, Manager>(); 
}); 

var manager = Mapper.Map<Employee, Manager>(new Employee { Id = 1, Name = "Fred" }); 

Console.WriteLine("Id: {0}", manager.MgrId); 
Console.WriteLine("Name: {0}", manager.MgrName); 

プロパティは、慣用的なソース識別子は、その後AutoMapperのprojectionを使用していない場合。

Mapper.CreateMap<Employee, Manager>() 
     .ForMember(dest => dest.MgrCode, opt => opt.MapFrom(src => src.ID)) 
     .ForMember(dest => dest.MgrName, opt => opt.MapFrom(src => src.Name)) 
+0

プロパティのケーシングは無視されますか? –

+0

はい、プロパティの囲みは無視されます。 – Romoku

+0

しかし、ここで私はautomapperを使用する必要があります。シリアライゼーションのような方法はありますか? – Murugavel

関連する問題