2011-01-14 41 views
8

Vì vậy, tôi có hai loại tùy chỉnh phức tạp như thế này (quá đơn giản hóa ví dụ này):Làm thế nào để chuyển đổi một kiểu tùy chỉnh phức tạp để một loại tùy chỉnh phức tạp

public class PendingProduct 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public int ColorCount { get; set; } 
} 

Hãy nói rằng tôi cần đối tượng này để biết làm thế nào để chuyển đổi bản thân với loại khác:

public class Product 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public ProductColors Colors { get; set;} 
} 

Vì vậy, khi tôi gọi một phương thức để chuyển đổi PendingProduct đến sản phẩm, tôi sẽ thực hiện một số logic tùy chỉnh mà cho biết thêm "ColorCount" số ProductColor đối tượng để các lớp sản phẩm. Điều này hoàn toàn đơn giản, nhưng kiến ​​trúc của lớp thực sự không liên quan ở đây.

gì câu hỏi chính của tôi là, là thế này:

gì là phương pháp thực hành tốt nhất để sử dụng để thực hiện việc chuyển đổi của một loại phức tạp để một loại phức tạp khi các thuộc tính của các đối tượng khác nhau?

Trong thế giới thực, các tính chất rất khác nhau và tôi sẽ viết một số logic tùy chỉnh để lập bản đồ những gì tôi cần từ Object A đến B. Object

Rõ ràng là tôi chỉ có thể viết một hàm mà phải mất một tham số đầu vào của đối tượng A và trả về đối tượng B, nhưng tôi đang tìm phương pháp "Thực hành tốt nhất". IConvertible có tham gia chơi ở đây không? Có cái gì đó giống như OOP hơn mà tôi có thể tận dụng thay vì chỉ viết một hàm để làm những gì tôi muốn?

Object Một nên luôn luôn biết làm thế nào để chuyển đổi bản thân để Object B.

EDIT: Là một mặt lưu ý, trong thế giới thực, đối tượng A và B đối tượng đều Entity Framework 4 thực thể. Tôi muốn lấy một "Sản phẩm đang chờ xử lý", chuyển đổi nó thành một thực thể Product mới, đính kèm nó vào bối cảnh dữ liệu và lưu lại.

Trả lời

18

Có nhiều cách có thể thực hiện được, nhưng chúng thực sự đun sôi để tự viết mã bản đồ, xử lý nó thông qua sự phản chiếu hoặc dựa trên một khung dựng sẵn như AutoMapper. Tôi đã trả lời một câu hỏi tương tự trong câu hỏi SO khác here.

tôi sẽ thêm nó vào đây để bạn tham khảo:

Thực tế bạn có thể

1.Reflection

public void Map<TSource, TDestination>(TSource source, TDestination destination) 
{ 
    var props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance); 
    var type = typeof(TDestination); 

    foreach (var prop in props) 
    { 
    object value = prop.GetValue(source, null); 

    var prop2 = type.GetProperty(prop.Name); 
    if (prop2 == null) 
     continue; 

    if (prop.PropertyType != prop2.PropertyType) 
     continue; 

    prop2.SetValue(destination, value, null); 
    } 
} 

2.Copy Constructor

public Employee(Person person) 
{ 
    // Copy properties 
} 

3.Implicit/Chuyển đổi rõ ràng

public static implicit operator Employee(Person person) 
{ 
    // Build instance and return 
} 

4.AutoMapper

Mapper.Map<Person, Employee>(person); 

5.Combination của 3/4:

public static implicit operator Employee(Person person) 
{ 
    return Mapper.Map<Person, Employee>(person); 
} 

Lưu ý về khai thác chuyển đổi ngầm/rõ ràng: Tôi tin vào cách sử dụng các bạn sẽ không tạo ra Mã tuân thủ CLS.

AutoMapper không cho phép bạn tùy chỉnh cách khác nhau thuộc vào loại mục tiêu được ánh xạ trên, ví dụ .:

Mapper.CreateMap<Person, Employee>() 
     .ForMember(e => e.Forename, o => o.MapFrom(p => p.Forename.ToLower())); 
0

Bạn sẽ không muốn lấy PendingProduct từ sản phẩm?

public class Product 
{  
    public string Name { get; set; }  
    public string Description { get; set; }  
    public ProductColors Colors { get; set; } 
} 

public class PendingProduct : Product 
{   
    public int ColorCount { get; set; } 
} 
Các vấn đề liên quan