2009-01-22 13 views
5

Napisałem klasę za pomocą pojedynczej statycznej metody, która kopiuje wartości właściwości z jednego obiektu do drugiego. Nie obchodzi go, jaki typ ma każdy obiekt, tylko że mają identyczne właściwości. Robi to, czego potrzebuję, więc nie będę go dalej rozwijać, ale jakie ulepszenia byś zrobił?Jak ulepszyłbyś tę płytką klasę kopiowania?

Oto kod:

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

Używam go w następujący sposób:

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

Jak używamy to z listy lub obiektu, który ma kilka List zawiera listy? –

+1

To byłaby * głęboka * kopia. Zasadniczo to samo, co powyżej, ale rekursywne, w którym znajduje się 'PropertyInfo' z' PropertyType', który jest dziedziczony z 'IEnumerable'. Musiałbyś oczywiście uporać się z oczyszczaniem celu, który można przeliczyć i rzeczy. –

Odpowiedz

6

Czy twoje DTOs serializacji? Spodziewam się, że w takim przypadku:

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

Należy jednak zauważyć, że nie zgadzam się z tym ogólnym podejściem. Wolałbym silny kontrakt na kopiowanie na waszych DTO, które wdraża każdy DTO.

2

Nowa metoda, która stworzyła nową instancję To i nazywa się metodą Copy() przed powrotem może być przydatny .

Jak to:

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

Zdecyduj, co chcesz zrobić, jeśli przekazano obiekty typów, które mają pewne właściwości, ale nie wszystkie. Sprawdź istnienie właściwości obiektu From w obiekcie To przed próbą ustawienia jego wartości. Wykonaj "właściwą rzecz", gdy dojdziesz do nieruchomości, która nie istnieje. Jeśli wszystkie właściwości publiczne muszą być identyczne, musisz sprawdzić, czy ustawiłeś je wszystkie na obiekcie To i obsługiwać przypadek, w którym nie zrobiłeś tego poprawnie.

Proponuję również, aby użyć atrybutów do dekoracji właściwości, które należy skopiować i zignorować inne. Umożliwiłoby to łatwiejsze przechodzenie między dwoma różnymi obiektami i utrzymanie niektórych właściwości publicznych, które są uzyskiwane, a nie przechowywane w obiekcie biznesowym.

4
  • Zmień nazwy parametrów typu zgodnie z konwencjami nazewnictwa, np. TFrom i TTo lub TSource i TDest (lub TDestination).

  • Wykonuj większość prac w typie ogólnym zamiast w ogólnej metodzie. To pozwala na buforowanie właściwości, a także pozwala na wnioskowanie o typie. Typ wnioskowania jest ważny w parametrze "TFrom", ponieważ umożliwia stosowanie typów anonimowych.

  • Można potencjalnie zrobić to oślepiająco szybko, dynamicznie generując kod, aby wykonać kopiowanie właściwości i zachować ją w delegacie, który jest ważny dla typu "z". Lub potencjalnie wygenerować go dla każdego z/do pary, co oznaczałoby, że faktyczne kopiowanie nie musiałoby w ogóle korzystać z odbicia! (Przygotowanie kodu byłaby jednorazowa trafić na parę typów, ale miejmy nadzieję, że nie będzie miał zbyt wiele par.)

Powiązane problemy