2013-07-16 12 views
8

Voglio sapere come mappare i campi di due oggetti diversi e assegnarvi i valori.Come mappare le proprietà di due oggetti diversi?

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; } 
} 

Ora ho un oggetto List. Voglio assegnare i valori alla classe "manager". Qualsiasi modo automatico per farlo. Posso farlo esplicitamente e assegnare valori ad esso. Ma il mio oggetto è molto grande, questo è il problema. Non voglio usare anche strumenti di terze parti.

Nota: non può avere alcun prefisso per il gestore. Può essere qualsiasi cosa. (Es: mgrId può essere come mgrCode)

+4

* "Non voglio utilizzare strumenti di terze parti troppo. "* Perchè no? –

+2

Usa la riflessione http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx –

+5

Solo un suggerimento: http://automapper.org/, è un ottimo strumento per convertire oggetti come questo. –

risposta

14

Si potrebbe utilizzare la riflessione per esso, anche ignorando l'involucro di proprietà (si noti il ​​employee.ID vs manager.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; } 
} 

Se non si conosce il prefisso Mgr, si poteva solo incontro da suffissi:

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)); 
} 

e un assunto molto stretta e poco pratico: mappatura B sull'ordine delle proprietà (se si prevede che i 2 tipi abbiano proprietà definite nella stessa sequenza e numero, l'unica differenza sono i nomi delle proprietà). Io non lo consiglio a chiunque di utilizzarlo nella vita reale, ma ancora, qui è (solo per renderlo più fragile :)):

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

Esiste un sovraccarico di ['PropertyInfo.GetValue'] (http://msdn.microsoft.com/en-us/library/hh194385.aspx) che accetta l'oggetto di origine. Esiste anche un sovraccarico a due argomenti di ['PropertyInfo.SetValue'] (http://msdn.microsoft.com/en-us/library/hh194291.aspx). – Romoku

+0

Corretto, a partire da 4.5. Compilavo con 3.5 :) aggiornerò la mia risposta. –

+0

Credo di aver usato molto .Net 4.5 ultimamente. Il riflesso – Romoku

10

Utilizzare la riflessione o AutoMapper. Raccomando quest'ultimo dato che scrivere un nuovo codice è dispendioso se non ha uno scopo.

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); 

Se le proprietà non hanno un identificatore fonte idiomatica quindi utilizzare automapper di 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

Ignora l'involucro della proprietà? –

+0

Sì ignorerà l'involucro della proprietà. – Romoku

+0

Ma qui ho bisogno di usare l'automapper. C'è un modo come la serializzazione? – Murugavel

Problemi correlati