2013-07-16 7 views
8

Ich möchte wissen, wie Felder von zwei verschiedenen Objekten zugeordnet werden und die Werte zuweisen.Wie werden Eigenschaften von zwei verschiedenen Objekten abgebildet?

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

Jetzt habe ich ein List-Objekt. Ich möchte die Werte der Klasse "manager" zuweisen. Jeder automatische Weg, dies zu tun. Ich kann es explizit tun und Werte zuweisen. Aber mein Objekt ist sehr groß, das ist das Problem. Ich möchte auch keine Tools von Drittanbietern verwenden.

Hinweis: Es kann kein Präfix für Manager haben. Es kann alles sein. (Beispiel: mgrID kann wie mgrCode sein)

+4

* "Ich mag nicht zu allen Tools von Drittanbietern verwenden. "* Warum nicht? –

+2

Verwenden Sie Reflektion http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx –

+5

Nur ein Vorschlag: http://automapper.org/, es ist ein großartiges Werkzeug, um Objekte wie diese zu konvertieren. –

Antwort

14

Sie Reflexion dafür verwenden könnte, auch durch die Eigenschaft Gehäuse zu ignorieren (man beachte die 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; } 
} 

Wenn Sie das Mgr Präfix nicht kennen, kann man nur Spiel durch Suffixe:

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

und eine sehr enge und unpraktisch Annahme: Mapping b auf der Eigentumsordnung (wenn Sie erwarten, dass die 2 Typen Eigenschaften in der gleichen Reihenfolge und Anzahl haben, der einzige Unterschied sind die Eigenschaftsnamen). Ich würde niemanden empfehle es im wirklichen Leben mit, aber immer noch, hier ist es (nur um es mehr zerbrechlich zu machen :)):

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

Es gibt eine Überladung von ['PropertyInfo.GetValue'] (http://msdn.microsoft.com/en-us/library/hh194385.aspx), die das Quellobjekt übernimmt. Es gibt auch eine Zwei-Argumente-Überladung von ['PropertyInfo.SetValue'] (http://msdn.microsoft.com/en-us/library/hh194291.aspx). – Romoku

+0

Richtig, beginnend mit 4.5. Ich kompilierte mit 3.5 :) Ich werde meine Antwort aktualisieren. –

+0

Ich denke, ich habe in letzter Zeit viel mit .Net 4.5 gearbeitet. – Romoku

10

Verwenden Sie Reflektion oder AutoMapper. Ich empfehle Letzteres, da das Schreiben neuen Codes verschwenderisch ist, wenn es keinen Zweck hat.

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

Wenn die Eigenschaften nicht haben eine idiomatische Quellenkennung dann projection AutoMapper des verwenden.

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

Wird die Eigenschaft Gehäuse ignoriert? –

+0

Ja, es ignoriert Eigentum Gehäuse. – Romoku

+0

Aber hier muss ich Autoadapter verwenden. Gibt es eine Art Serialisierung? – Murugavel

Verwandte Themen