2012-07-08 3 views
2

동일한 유형의 두 객체를 비교하고 차이를 FieldChange 객체의 목록으로 반환합니다. 지금은 조금씩 차선책 인 것처럼 각 필드 비교를 나열하고 있습니다.이 C# 비교 코드를 좀 더 일반적인 방법으로 만들 수 있습니까?

반복을 피하기 위해 아래 코드를 리팩토링하는 더 깨끗한 방법이 있습니까? 아래에 두 세트의 코드가 있지만 실제로는 약 20 가지 비교가 있습니다.

var changes = new List<FieldChange>(); 
if (proposedUpdatedProject.StatusId != existingProject.StatusId) 
{ 
    var previousStatusName = existingProject.StatusShortName; 
    existingProject.Status = ProjectModel.Repository.Fetch<ProjectStatus>(proposedUpdatedProject.StatusId); 
    changes.Add(new FieldChange { FieldName = "Status", PreviousValue = previousStatusName, NewValue = existingProject.StatusShortName }); 
} 

if (proposedUpdatedProject.TechOwnerId != existingProject.TechOwnerId) 
{ 
    var previousTechOwnerName = existingProject.TechOwnerName; 
    existingProject.TechOwner = ProjectModel.Repository.Fetch<Person>(proposedUpdatedProject.TechOwnerId); 
    changes.Add(new FieldChange { FieldName = "Tech Owner", PreviousValue = previousTechOwnerName, NewValue = existingProject.TechOwnerName }); 
} 

참고 : 모든 개체는 BaseObj라는 동일한 개체에서 파생됩니다. 또한 FieldChange 객체 (id 대 Name 속성)에 비교 가능한 필드의 값을 넣는 것이 아닙니다.

+5

당신은 [codereview.se]를 시도해 볼 수 있습니다 ... – Adam

답변

2

ComparableAttribute과 같은 메서드 attribute을 만들 수 있습니다. 그런 다음이 속성을 사용하여 이러한 객체의 모든 메소드를 장식 할 수 있습니다.

비교를 수행하는 방법에 리플렉션을 사용하고 모든 Comparable 속성을 반복 할 수 있습니다. 코드는 훨씬 짧을 것입니다 (하나의 반복, 20 if 문 대신).

특정 속성에 대한 사용자 지정 정보가 필요하면 매개 변수로 ComparableAttribute 특성을 통해 지정할 수 있습니다.

compare 메소드는 여전히 두 개의 인스턴스를 매개 변수로 사용하지만 더 작은 구현으로 끝납니다. 심지어 유형에 대해 PropertyInfo을 캐시 할 수 있으므로 각 비교시 반영하지 않아도됩니다.

existingProject 

을 그리고 모든 필드를 비교 :

+0

이 접근법으로 StatusId와 StatusShortName 사이의 관계를 어떻게 나타낼 지 명확히 할 수 있습니까? – leora

+0

@leora : 'ComparableAttribute'의 매개 변수로 처리 할 것입니다. 예 :'Comparable (Name = "Status", ValueProperty = "StatusShortName", LookupPropertyType = typeof (ProjectStatus))'. compare 함수에서 이것을 사용하여 현재 if 문 안에있는 코드를 일반화 할 수 있습니다. –

+0

@leora : 이드를 놓쳤습니다. 'Comparable (Name = "Status", IdProperty = "StatusId", ValueProperty = "StatusShortName", LookupPropertyType = typeof (ProjectStatus))'이어야합니다. 생각 해보려면, 이것은 메소드 속성이 아닌 클래스 속성이어야합니다. 객체 속성의 서브 세트 만 필요하기 때문입니다. –

0

왜 구조에 반영하지. 이런 식으로 코드를 작성하면 StatusID와 StatusName 사이의 연관성과 같은 문제에 상당히 많은 정보가 추가되지만 적절한 명명 규칙을 선택하면 잠재적으로 모든 작업을 자동화 할 수 있습니다.

0

INotifyPropertyChanged 인터페이스를 사용하지 않으시겠습니까? 이에 대한 정보는 here을보십시오. 이벤트를 구현하고 이벤트에 등록하기 만하면됩니다. 하나 더 link

관련 문제