2009-01-22 29 views
5

Tôi đã viết một lớp với một phương thức tĩnh duy nhất sao chép các giá trị thuộc tính từ một đối tượng này sang đối tượng khác. Nó không quan tâm đến từng loại đối tượng, chỉ có chúng có các thuộc tính giống hệt nhau. Nó làm những gì tôi cần, vì vậy tôi không kỹ thuật hơn nữa, nhưng bạn sẽ làm những cải tiến nào?Bạn sẽ cải thiện lớp sao chép nông này như thế nào?

Dưới đây là các mã:

public class ShallowCopy 
{ 
    public static void Copy<From, To>(From from, To to) 
     where To : class 
     where From : class 
    { 
     Type toType = to.GetType(); 
     foreach (var propertyInfo in from.GetType().GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance)) 
     { 
      toType.GetProperty(propertyInfo.Name).SetValue(to, propertyInfo.GetValue(from, null), null); 
     } 
    } 
} 

Tôi đang sử dụng nó như sau:

EmployeeDTO dto = GetEmployeeDTO(); 
Employee employee = new Employee(); 
ShallowCopy.Copy(dto, employee); 
+0

Cách chúng tôi sử dụng mã này với Danh sách hoặc đối tượng có một số Danh sách danh sách trong đó? –

+1

Đó sẽ là bản sao * sâu *. Về cơ bản giống như ở trên nhưng đệ quy nơi bạn tìm thấy một 'PropertyInfo' với một' PropertyType' được thừa kế từ 'IEnumerable'. Bạn sẽ cần phải đối phó với thanh toán bù trừ các mục tiêu enumerable và mọi thứ, rõ ràng. –

Trả lời

6

Are DTOs bạn serializable? Tôi mong chờ như vậy, trong trường hợp này:

MemberInfo[] sm = FormatterServices.GetSerializableMembers(typeof(From)); 
object[] data = FormatterServices.GetObjectData(from, sm); 
FormatterServices.PopulateObjectMembers(to, sm, data); 

Nhưng lưu ý rằng tôi không thực sự đồng ý với phương pháp chung này. Tôi muốn có một hợp đồng mạnh mẽ để sao chép trên DTO của bạn mà mỗi DTO thực hiện.

2

Một phương pháp mới đã tạo ra một thể hiện mới của To và gọi là Copy() phương pháp trước khi trở về có thể có ích .

Như thế này:

public static To Create<From, To>(From from) 
    where To : class, new() 
    where From : class 
{ 
    var to = new To(); 
    Copy(from, to); 
    return to; 
} 
1

Quyết định những gì bạn muốn làm nếu vượt qua các đối tượng thuộc loại chia sẻ một số thuộc tính nhưng không phải tất cả. Kiểm tra sự tồn tại của thuộc tính trong đối tượng From trong đối tượng To trước khi cố đặt giá trị của nó. Làm "điều đúng" khi bạn đến một tài sản không tồn tại. Nếu tất cả các thuộc tính công cộng cần phải giống hệt nhau, thì bạn sẽ cần phải kiểm tra xem bạn đã đặt tất cả chúng trên đối tượng To và xử lý trường hợp bạn không thích hợp.

Tôi cũng khuyên bạn nên sử dụng các thuộc tính để trang trí các thuộc tính cần được sao chép và bỏ qua những người khác. Điều này sẽ cho phép bạn đi qua lại giữa hai đối tượng khác nhau dễ dàng hơn và tiếp tục duy trì một số thuộc tính công khai có nguồn gốc thay vì được lưu trữ trên đối tượng kinh doanh của bạn.

4
  • Thay đổi tên thông số loại của bạn để tuân thủ quy ước đặt tên, ví dụ: TFrom và TTo, hoặc TSource và TDest (hoặc TDestination).

  • Làm hầu hết công việc của bạn theo kiểu chung chung thay vì chỉ bằng một phương pháp chung chung. Điều đó cho phép bạn lưu trữ các thuộc tính, cũng như cho phép suy luận kiểu. Kiểu suy luận là quan trọng đối với tham số "TFrom", vì nó sẽ cho phép sử dụng các kiểu ẩn danh.

  • Bạn có khả năng biến nó nhanh chóng bằng cách tạo mã động để thực hiện sao chép thuộc tính và giữ nó trong đại biểu hợp lệ cho loại "từ". Hoặc có khả năng tạo ra nó cho mỗi từ/cặp, có nghĩa là sao chép thực tế sẽ không cần phải sử dụng sự phản chiếu chút nào! (Chuẩn bị mã sẽ là lần truy cập một lần cho mỗi loại, nhưng hy vọng bạn sẽ không có quá nhiều cặp.)

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