2012-02-22 1 views
3

같은 유형의 두 객체를 비교하는 메소드를 정의해야합니다. 객체의 유형은 구체적이지 않습니다. 개체가 DLL 형식 일 수 있으므로 Equals 메서드를 재정의 할 수 없습니다. 나는 이것을 반영해야만한다. 이 코드는 객체의 모든 멤버가 프리미티브 유형 인 경우 작동합니다. 그러나 객체가 원시가 아닌 필드를 가지고있을 때는 작동하지 않습니다. 리플렉션으로 어떻게 할 수 있습니까?알 수없는 유형의 두 객체가 동일한 지 확인하고 모든 필드를 비교하십시오.

public bool Equals(object obj1, object obj2) 
{ 
    List<FieldInfo> fieldInfos = obj1.GetType().GetFields().ToList(); 
    return (fieldInfos.Select(fieldInfo => new {fieldInfo, type = fieldInfo.GetType()}) 
     .Where(@t => @t.type.IsPrimitive || @t.type == typeof(string) || @t.type == typeof(Decimal)) 
     .Select(@t => @t.fieldInfo)).All(fieldInfo => fieldInfo.GetValue(obj1).Equals(fieldInfo.GetValue(obj2))); 
} 

답변

0

하고자하는 내가 유틸리티 함수가 두 객체를 비교하려면 정확히 무엇을 할 것인가이 lib 디렉토리에 대해 이야기하고있다. 내가 포함 할 유형의 모든

  1. 원시 형
  2. 는 IEnumerable (처럼 DICT 또는 목록)를 구현하는 클래스

그래서 난 일반 및 반사 할 사용

  • 모든 클래스 그래서. 나는 이것을 이렇게 코딩한다.

     public static bool CompareObjects<T>(T expectInput, T actualInput) 
        { 
         // If T is primitive type. 
         if (typeof(T).IsPrimitive) 
         { 
          if (expectInput.Equals(actualInput)) 
          { 
           return true; 
          } 
    
          return false; 
         } 
    
         if (expectInput is IEquatable<T>) 
         { 
          if (expectInput.Equals(actualInput)) 
          { 
           return true; 
          } 
    
          return false; 
         } 
    
         if (expectInput is IComparable) 
         { 
          if (((IComparable)expectInput).CompareTo(actualInput) == 0) 
          { 
           return true; 
          } 
    
          return false; 
         } 
    
         // If T is implement IEnumerable. 
         if (expectInput is IEnumerable) 
         { 
          var expectEnumerator = ((IEnumerable)expectInput).GetEnumerator(); 
          var actualEnumerator = ((IEnumerable)actualInput).GetEnumerator(); 
    
          var canGetExpectMember = expectEnumerator.MoveNext(); 
          var canGetActualMember = actualEnumerator.MoveNext(); 
    
          while (canGetExpectMember && canGetActualMember && true) 
          { 
           var currentType = expectEnumerator.Current.GetType(); 
           object isEqual = typeof(Utils).GetMethod("CompareObjects").MakeGenericMethod(currentType).Invoke(null, new object[] { expectEnumerator.Current, actualEnumerator.Current }); 
    
           if ((bool)isEqual == false) 
           { 
            return false; 
           } 
    
           canGetExpectMember = expectEnumerator.MoveNext(); 
           canGetActualMember = actualEnumerator.MoveNext(); 
          } 
    
          if (canGetExpectMember != canGetActualMember) 
          { 
           return false; 
          } 
    
          return true; 
         } 
    
         // If T is class. 
         var properties = typeof(T).GetProperties(); 
         foreach (var property in properties) 
         { 
          var expectValue = typeof(T).GetProperty(property.Name).GetValue(expectInput); 
          var actualValue = typeof(T).GetProperty(property.Name).GetValue(actualInput); 
    
          if (expectValue == null || actualValue == null) 
          { 
           if (expectValue == null && actualValue == null) 
           { 
            continue; 
           } 
    
           return false; 
          } 
    
          object isEqual = typeof(Utils).GetMethod("CompareObjects").MakeGenericMethod(property.PropertyType).Invoke(null, new object[] { expectValue, actualValue }); 
    
          if ((bool)isEqual == false) 
          { 
           return false; 
          } 
         } 
    
         return true; 
        }