2012-02-22 4 views
3

同じ型の2つの異なるオブジェクトを比較するメソッドを定義する必要があります。オブジェクトのタイプは特定ではありません。オブジェクトはDLLタイプなので、Equalsメソッドをオーバーライドすることはできません。私はこれを反映させる必要があります。このコードは、オブジェクトのすべてのメンバーがプリミティブ型である場合に機能します。しかし、オブジェクトがプリミティブでないフィールドを持っている場合は機能しません。どのように私は反射でそれを行うことができますか?型が不明な2つのオブジェクトが等しいかどうかをチェックし、すべてのフィールドを比較します

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

欠けている私は、効用関数は任意の2つのオブジェクトを比較したい正確に何を行います。このlibに知らされています。私がカバーしたいタイプのすべてが

  1. プリミティブ型
  2. (Dictのか、リストなど)のIEnumerableを実装するクラス
  3. どれクラス

ので、私が行う一般的な反射を使用していますそう。私はこれのようにコード化します。

 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; 
    } 
関連する問題