2014-10-20 2 views
0

일반 텍스트 상자와 언 바운드 datagridview가 포함 된 '송장'WinForm C#이 있습니다. 'Invoice'클래스 개체를 사용하여 양식 필드의 값을 저장했습니다. DataGridview 행은 'Invoice'의 List < SubInvoice 속성에 저장됩니다.리플렉션을 사용하여 목록의 개체 비교

public static bool CompareObjects(object original, object altered) 
{ 
    Type o = original.GetType(); 
    Type a = altered.GetType(); 

    foreach (PropertyInfo p in o.GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
    { 
     Console.WriteLine("Original: {0} = {1}", p.Name, p.GetValue(original, null)); 
     Console.WriteLine("Altered: {0} = {1}", p.Name, p.GetValue(altered, null)); 

     if (p.GetValue(original, null).ToString() != p.GetValue(altered, null).ToString()) 
     { 
      //Console.WriteLine("Not Equal"); 
      return false; 
     } 
    } 

    return true; 
} 

나는 원래 '송장'개체를 통해 루프 반사를 사용하고 변경 '송장'과 비교하는 방법으로 글로벌 클래스를 사용하고 있습니다. 차이가있을 경우 사용자에게 인보이스 저장 여부를 알립니다.

위의 방법은 'Invoice'클래스의 모든 속성에서 올바르게 작동하지만 각 DataGridrow의 값을 'SubInvoice'클래스 개체에 저장하는 List를 확인하는 방법을 알지 못합니다. 목록에있는 개체.

누군가 나에게 도움을 줄 수 있습니까? 나는 또한 stackoverflow 및 다른 포럼에서 비슷한 스레드를 확인했지만 헛된.

업데이트 : 모든 유형의 클래스를 검사하는 글로벌 제네릭 메소드를 만들어야합니다. '송장', '고객'이 될 수 있습니다. 목적은 특정 인스턴스에서 양식에 대한 변경 사항을 추적하고 저장하도록 사용자에게 프롬프트하는 것입니다.

+0

과'a'는'a'가 가지고있는 속성과 동일한 모든 속성을 가지지 않는 한 다른 타입입니다. 평등 비교로 사용할 수있는 값을 반환하도록 ToString()을 오버로드하지 않는 한 속성 중 하나라도 클래스 또는 구조체이면 의도 한대로 작동하지 않습니다. 마지막으로'a'가'o'가 가지고 있지 않은 속성을 가질 경우 가능한 차이를 감지하지 못할 것입니다. –

+0

물론 가능합니다. o와 a는 둘 다 동일한 송장 오브젝트입니다. 유일한 차이점은 보유한 가치입니다. 예를 들어, o (원본에서와 같이)는 총 값 (double totalAmount 속성)으로 300.25 달러를 가질 수 있고 (변경된 것처럼) 동일한 속성 필드에서 총 값으로 $ 525.16을 가질 수 있습니다.'Invoice'클래스에는 double, int, datetime 속성과 DataGridview 값의 각 행을 나타내는 'SubInvoice'클래스 객체 목록이 포함 된 List < subinvoice> 속성이 있습니다. – furor

+0

당신은 http://www.cyotek.com/blog/comparing-the-properties-of-two-objects-via-reflection을 확인하십시오. – Damith

답변

0

보류중인 변경 사항을 저장하라는 메시지 만 표시하려면 검은 색 마술을 사용하는 대신 INotifyPropertyChanged을 구현해야합니다.

+0

black magic, haha. 언 바운드 datatable datagridview에서 작동 할까? 관심사는 '송장'클래스의 목록 객체입니다 다른 클래스가 포함되어 있습니다 – furor

+0

그 클래스에 인터페이스도 구현하십시오. 당신은 원래 객체와 변경된 객체를 가지고 있다고 말하면서 어떻게 든 객체를 수정하고 있습니다. 그리드가 경계되어 있는지 여부 –

+0

두 가지 객체 목록 비교 : "동일한"객체 인 색인, 새로운 색인 인 객체, 삭제 된 객체 중 어떤 객체인지를 어떻게 알 수 있습니까? INotifyPropertyChanged를 구현하면 ObservableCollection 을 사용하여 컬렉션 변경 사항을 모니터링 할 수 있습니다. –

0

전에 본 적이있는 트릭 중 하나는 객체를 직렬화 가능으로 표시 한 다음 문자열로 직렬화하고 문자열을 비교하는 것입니다. 가장 효율적인 방법은 아니지만 쉽고 빠르며 거의 모든 종류의 데이터 클래스에서 작동합니다. 다른 클래스에 대한 참조가있는 "복잡한"중첩 클래스에 대해서도 작동합니다.

한 가지 단점은 특별히 무엇이 변경되었는지 간단하게 알려주지 않는다는 것입니다.

+0

예 가능할 수 있습니다. 나는 지금 시험해 볼 것이다. 감사! – furor

0

모두에게 감사드립니다.

리플렉션을 통해 글로벌 제네릭 메소드를 만들려고하면서 다음 기사를 발견했습니다. 사람이 관심이 있다면

http://www.c-sharpcorner.com/UploadFile/1a81c5/custom-extension-method-to-compare-list-in-C-Sharp/

여기에 코드입니다.

public static bool CompareObjects(object original, object altered) 
{ 
    bool result = true; 

    //Get the class 
    Type o = original.GetType(); 
    Type a = altered.GetType(); 

    //Cycle through the properties. 
    foreach (PropertyInfo p in o.GetProperties(BindingFlags.Public | BindingFlags.Instance)) 
    { 
     Console.WriteLine("Original: {0} = {1}", p.Name, p.GetValue(original, null)); 
     Console.WriteLine("Altered: {0} = {1}", p.Name, p.GetValue(altered, null)); 

     if (!p.PropertyType.IsGenericType) 
     { 
      if (p.GetValue(original, null) != null && p.GetValue(altered, null) != null) 
      { 
       if (!p.GetValue(original, null).ToString().Equals(p.GetValue(altered, null).ToString())) 
       { 
        result = false; 
        break; 
       } 
      } 
      else 
      { 
       //If one is null, the other is not 
       if ((p.GetValue(original, null) == null && p.GetValue(altered, null) != null) || (p.GetValue(original, null) != null && p.GetValue(altered, null) == null)) 
       { 
        result = false; 
        break; 
       } 
      } 
     } 
    } 

    return result; 
} 

public static bool CompareLists<T>(this List<T> original, List<T> altered) 
{ 
    bool result = true; 

    if (original.Count != altered.Count) 
    { 
     return false; 
    } 
    else 
    { 
     if (original != null && altered != null) 
     { 
      foreach (T item in original) 
      { 
       T object1 = item; 
       T object2 = altered.ElementAt(original.IndexOf(item)); 

       Type objectType = typeof(T); 

       if ((object1 == null && object2 != null) || (object1 != null && object2 == null)) 
       { 
        result = false; 
        break; 
       } 

       if (!CompareObjects(object1, object2)) 
       { 
        result = false; 
        break; 
       } 
      } 
     } 
     else 
     { 
      if ((original == null && altered != null) || (original != null && altered == null)) 
      { 
       return false; 
      } 
     } 
    } 

    return result; 
} 

사용법 : 경우 (xx.CompareObjects (searchedInvoice, alteredInvoice) | xx.CompareLists (searchedInvoice.SubInvoice, alteredInvoice.SubInvoice)!!) O``경우이 코드는 예외가 발생합니다