2013-08-20 4 views
1

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

public class MyEntity 
{ 
    public string FirstName; 
    public string LastName; 
} 

Я хотел бы сравнить два экземпляра из MyEntity, и создать новый MyEntity экземпляр, содержащий только различия в значения между двумя другими экземплярами. При этом свойства, равные, будут иметь значение null в новом объекте.

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

MyEntity entity1 = new MyEntity() { FirstName = "Jon", LastName = "Doh" }; 
MyEntity entity2 = new MyEntity() { FirstName = "Jon", LastName = "The Great" }; 
MyEntity diffEntity = CreateDiffEntity(entity1, entity2); // TODO 

привести следующие diffEntity значения:

{ 
    FirstName: null, 
    LastName: "The Great" 
} 

Мы можем предположить, что все свойства обнуляемые.

В случае, если значения не совпадают, новый объект должен содержать значение свойства второго объекта.

Пожалуйста, предположим, у меня есть много типов сущностей, с различными свойствами definitionsm
Таким образом, мне нужно решение, которое может быть использовано на других типах классов, чем MyEntity, и это не потребует изменений, когда новые свойства добавляются к классам ,

Конечная цель - дать возможность мобильному приложению клиента отправить DTO, который содержит только изменения, внесенные в сущность, в приложение ASP.NET MVC WebAPI.

Как это можно сделать правильно?

+0

Вы уже пытались что-нибудь и застревают, или просто разместил вопрос и подумать, что кто-то сделает все для вас? :) – MarcinJuraszek

+1

diffEntity примет значение второго объекта, если они не совпадают ...? – Jonesopolis

+0

Звучит как интересный вопрос, вы можете сделать это в конструкторе класса, сравнивая значения 'entity1' и' entity2'. Вы вообще что-то пробовали или это всего лишь вопрос о домашнем задании? – tnw

ответ

2

Там большая проблема со всем этим подходом, вы не можете ничего установить в null. Вероятно, вы просто должны отправлять полную сущность или, если у вас есть интерфейс (ы), который разрешает редактировать только подмножество свойств, создайте DTO для каждого интерфейса с теми изменениями, которые могут произойти там.


Во всяком случае, только потому, что она созрела для некоторого простого улучшения, это общее, и слегка модифицирован, решение, основанное на BrianV's solution.(С использованием object.Equals вместо != позволяет вещи можно сравнить их значениями, а не только их идентичностей)

public T Compare<T>(T first, T second) where T : new() 
{ 
    T result = new T(); 
    Type t = typeof(T); 
    PropertyInfo[] propertyInfoList = t.GetProperties(); 

    foreach (PropertyInfo propertyInfo in propertyInfoList) 
    { 
     object value1 = propertyInfo.GetValue(first, null); 
     object value2 = propertyInfo.GetValue(second, null); 

     if (!object.Equals(value1, value2)) 
      propertyInfo.SetValue(result, value2, null); 
    } 

    return result; 
} 

использовать его как:

MyEntity entity1 = new MyEntity() { FirstName = "Jon", LastName = "Doh" }; 
MyEntity entity2 = new MyEntity() { FirstName = "Jon", LastName = "The Great" }; 
MyEntity diffEntity = Compare(entity1, entity2); 
0

Вы можете решить проблему следующим образом:

public MyEntity CreateDiffEntity(MyEntity entity1, MyEntity entity2) { 
    MyEntity diff = new MyEntity(); 
    diff.FirstName = !entity1.FirstName.equals(entity2.FirstName) ? entity2.FirstName : string.Empty; 
    diff.LastName = !entity1.LastName.equals(entity2.LastName) ? entity2.LastName : string.Empty; 
    return diff; 
} 
+0

Вы хотите 'null', а не' string.Empty'. См. Пример вывода OP. – tnw

+1

@tnw yepp, но это всего лишь пример кода. OP может заменить на null самостоятельно. –

0

вы можете сделать это в объекте инициализаторе

MyEntity entity1 = new MyEntity() { FirstName = "Jon", LastName = "Doh" }; 
MyEntity entity2 = new MyEntity() { FirstName = "Jon", LastName = "The Great" }; 

MyEntity diffEntity = new MyEntity 
    { 
     FirstName = (entity1.FirstName == entity2.FirstName) ? null : entity2.FirstName, 
     LastName = (entity1.LastName == entity2.LastName) ? null : entity2.LastName 
    }; 
+0

Мне нужно решение, которое можно использовать для других типов, чем 'MyEntity', и это не потребует изменений при добавлении новых свойств в классы. – Liel

+0

Google почти полностью использует код, уже написанный – Jonesopolis

+1

@Liel. Тогда решение Брайана может быть тем, что вы ищете. – tnw

4

Вы можете использовать Reflection, чтобы решить эту проблему. Основная суть этого является:

public void Compare(object first,object second, object result) 
    { 
     Type t = first.GetType(); 
     PropertyInfo[] propertyInfoList = t.GetProperties(); 

     foreach (PropertyInfo propertyInfo in propertyInfoList) 
     { 
      object value1= propertyInfo.GetValue(first, null); 
      object value2 = propertyInfo.GetValue(second, null); 

      if (value1 != value2) 
      { 
       propertyInfo.SetValue(result, value1, null); 
      } 
      else 
      { 
       propertyInfo.SetValue(result, null, null); 
      } 

     } 
    } 

И затем использовать его как это:

MyType result = new MyType(); 
Compare(object1,object2, result); 

Он может быть использован в качестве метода расширения или члена на одном из ваших лиц.

1

Здесь вы идете:

static public T CreateDiffEntity<T>(T entity1, T entity2) where T : new() 
    { 
     T result = new T(); 
     foreach (var property in typeof(T).GetProperties()) 
     { 
      var valuePropertyEntity1 = property.GetValue(entity1); 
      var valuePropertyEntity2 = property.GetValue(entity2); 
      if (!valuePropertyEntity1.Equals(valuePropertyEntity2)) 
       property.SetValue(result, valuePropertyEntity2); 
      else 
       property.SetValue(result, null); 
     } 
     return result; 
    } 
Смежные вопросы