2015-12-01 1 views
0

Я пишу программу, которая получает данные из базы данных и сравнивает его значение по значению для старых данных, а затем должна быть в состоянии:Лучший способ создать класс для сравнения экземпляров себя

  1. Выходные старые данные
  2. Выходные данные Новый
  3. Выход только Разницы

Таким образом, для простоты предположим, что я создал следующий класс для хранения значений:

class MyClass 
{ 
    // These fields will not be compared: 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string NONCompField1 { get; set; } 
    public int NONCompField2 { get; set; } 

    // These fields WILL be compared: 
    public string CompField1 { get; set; } 
    public int CompField2 { get; set; } 
    public int CompField3 { get; set; } 
    public double CompField4 { get; set; } 
} 

И, как следует из названия в моем примере, я хочу сравнить старые и новые значения, но только на основе CompFields, чтобы найти различия.

Я знаю, что могу жестко закодировать решение следующим образом:

public IEnumerable<Tuple<string, string, string>> GetDiffs(MyClass Other) 
    { 
     var RetVal = new List<Tuple<string, string, string>>(); 

     if (CompField1 != Other.CompField1) 
      RetVal.Add(Tuple.Create("CompField1", CompField1, Other.CompField1)); 
     if (CompField2 != Other.CompField2) 
      RetVal.Add(Tuple.Create("CompField2", CompField2.ToString(), Other.CompField2.ToString())); 
     if (CompField3 != Other.CompField3) 
      RetVal.Add(Tuple.Create("CompField3", CompField3.ToString(), Other.CompField3.ToString())); 
     if (CompField4 != Other.CompField4) 
      RetVal.Add(Tuple.Create("CompField4", CompField4.ToString(), Other.CompField4.ToString())); 

     return RetVal; 
    } 

И это дает мне обратно Tuple<string, string, string> из (Field_Name, Current_Value, Old_Value) и что работает просто отлично, но я ищу более удобный, способный динамический способ сделать это, что позволит добавлять новые поля в будущем - будь то CompareFields (необходимо обновить GetDiffs) или NONCompFields (нет необходимости обновлять GetDiffs).

Моей первой мыслью было бы использовать DataAnnotations, а затем отражать, чтобы найти поля с определенным атрибутом и прокрутить их для метода GetDiffs, но это похоже на чит/плохой способ делать что-то.

Есть ли лучший/более простой способ сделать это, что свести к минимуму необходимость обновления дополнительного кода?

Спасибо !!!

+1

Если вы не возражаете против использования инструментов сторонних разработчиков, рассмотрите [это] (http://comparenetobjects.codeplex.com) –

+0

Большое спасибо, @Ювальчжаков. Я стараюсь избегать использования внешней библиотеки, если это возможно, но это, безусловно, хорошо знать! Благодаря! –

ответ

1

FYI - для кто-то еще, кто хочет сделать то же самое, что и я сделал здесь, я в конечном итоге изменил код, который нашел here.

Это позволило мне передать список имен свойств, используемых для сравнения (хотя пример делает обратное - он имеет список имен для игнорирования, но это простое изменение), а модификации были довольно просто.

Надеюсь, что это поможет хотя бы направить других в такую ​​же ситуацию.

1

Создать список делегатов, выступающую деталь к каждому из различных свойств, которые вы хотите сравнить, а затем сравнить результаты каждого из этих выступов на двух элементов:

public IEnumerable<Tuple<string, string, string>> GetDiffs(MyClass Other) 
{ 
    var comparisons = new[] 
    { 
     Tuple.Create<string, Func<MyClass, object>>("CompField1", item => item.CompField1), 
     Tuple.Create<string, Func<MyClass, object>>("CompField2", item => item.CompField2), 
     Tuple.Create<string, Func<MyClass, object>>("CompField3", item => item.CompField3), 
     Tuple.Create<string, Func<MyClass, object>>("CompField4", item => item.CompField4), 
    }; 

    return from comparison in comparisons 
      let myValue = comparison.Item2(this) 
      let otherValue = comparison.Item2(Other) 
      where !object.Equals(myValue, otherValue) 
      select Tuple.Create(comparison.Item1, 
       myValue.ToString(), 
       otherValue.ToString()); 
} 
+0

Сервис, большое вам спасибо. Но, похоже, здесь все еще есть необходимость обновлять метод GetDiffs каждый раз, когда я добавляю новое (сопоставимое) свойство. Есть ли причина, почему этот способ лучше, чем использование какой-либо формы DataAnnotation/Reflection (что означало бы только украшение свойства во время создания)? –

+0

@JohnBustos Вы можете сделать это, если хотите. – Servy

+0

:) - Поистине, просто интересно, была ли причина для твоего пути? Если по какой-то причине это лучше (я все еще очень нуб и заинтересован в изучении лучших практик, если это вообще возможно) –

 Смежные вопросы

  • Нет связанных вопросов^_^