2013-07-16 45 views
8

Tôi muốn biết cách ánh xạ các trường của hai đối tượng khác nhau và gán giá trị cho nó.Cách ánh xạ các thuộc tính của hai đối tượng khác nhau?

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

Bây giờ tôi có một đối tượng List. Tôi muốn gán giá trị cho lớp "người quản lý". Bất kỳ cách tự động nào để thực hiện điều đó. Tôi có thể làm điều đó một cách rõ ràng và gán giá trị cho nó. Nhưng đối tượng của tôi là rất lớn thats vấn đề. Tôi cũng không muốn sử dụng bất kỳ công cụ của bên thứ ba nào.

Lưu ý: Nó không thể có bất kỳ tiền tố nào cho người quản lý. Nó có thể là bất cứ thứ gì. (Ví dụ: mgrId có thể giống như mgrCode)

+4

* "Tôi không muốn sử dụng bất kỳ công cụ của bên thứ ba quá. "* Tại sao không? –

+2

Sử dụng sự phản chiếu http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx –

+5

Chỉ cần một gợi ý: http://automapper.org/, một công cụ tuyệt vời của nó để chuyển đổi các đối tượng như thế này. –

Trả lời

14

Bạn có thể sử dụng phản ánh cho nó, thậm chí bằng cách bỏ qua vỏ bất động sản (chú ý 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; } 
} 

Nếu bạn không biết tiền tố Mgr, bạn chỉ có thể phù hợp bởi hậu tố:

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

một giả định rất hẹp và không thực tế: lập bản đồ b ased trên thứ tự tài sản (nếu bạn đang mong đợi 2 loại có thuộc tính được định nghĩa trong cùng một chuỗi và số, sự khác biệt duy nhất là tên thuộc tính). Tôi sẽ không khuyên bất cứ ai sử dụng nó trong cuộc sống thực, nhưng vẫn còn, ở đây nó là (chỉ để làm cho nó thêm mong manh :)):

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

Có quá tải ['PropertyInfo.GetValue'] (http://msdn.microsoft.com/en-us/library/hh194385.aspx) có đối tượng nguồn. Ngoài ra còn có hai quá tải đối số của ['PropertyInfo.SetValue'] (http://msdn.microsoft.com/en-us/library/hh194291.aspx). – Romoku

+0

Đúng, bắt đầu bằng 4,5. Tôi đã biên dịch với 3.5 :) Tôi sẽ cập nhật câu trả lời của mình. –

+0

Tôi đoán tôi đã sử dụng .Net 4.5 rất nhiều gần đây. – Romoku

10

Sử dụng phản chiếu hoặc AutoMapper. Tôi khuyên bạn nên sau khi viết mã mới là lãng phí nếu nó không có một mục đích.

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

Nếu thuộc tính không có định danh nguồn thành ngữ thì hãy sử dụng 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

Nó có bỏ qua vỏ bọc tài sản không? –

+0

Có, nó sẽ bỏ qua thuộc tính vỏ. – Romoku

+0

Nhưng ở đây tôi cần phải sử dụng automapper. Có cách nào giống như serialization không? – Murugavel

Các vấn đề liên quan