C# сравнить значения двух классов

Nechto

Здравствуйте!Подскажите пожалуйста, как сравнить значения свойств двух классов с разной структурой, но наследуемых один интерфейс?
public interface IA
{ 
 int Id { get; set; }
 string Name { get; set; }
}
public class A : IA
{ 
 public int Id { get; set; }
 public string Name { get; set; }
}
public class B : IA
{ 
 public int Id { get; set; }
 public string Name { get; set; }
 public string Test { get; set; }
}

IA c1 = new A (1, "1111");
IA c2 = new B (1, "1111", "2222");

if (c1 == c2) //Как правильно определить, что значения этих классов схожи относительно интерфейсов?
24 ответа

Nechto

Nechto,Сделайте их наследниками)
Не совсем понял?


Nechto

Nechto,Сделайте их наследниками)
И что это даст в вопросе сравнения экземпляров?


Nechto

наследовать интерфейс от IEqualityComparerhttps://msdn.microsoft.com/ru-ru/library/ms132151(v=vs.110).aspx и сравнивать с помощью интерфейса


Nechto

И что это даст в вопросе сравнения экземпляров?
сравнивать не придется.Схожие классы не только интерфейсом делаются.


Nechto

сравнивать не придется.Схожие классы не только интерфейсом делаются.
С чего же сравнивать не придется, когда автору требуется именно сравнить? И каким боком тут схожесть классов не только интерфейсом?


Nechto

Сон Веры Павловны,Ну понятно, что я расширил вопрос ТС


Nechto

Сон Веры Павловны,Ну понятно, что я расширил вопрос ТС
Я сильно подозреваю, что направление расширения было понятно только расширившему.


Nechto

Сон Веры Павловны,По ООП в коде выше делают класс Б наследником над классом А или оба класса над абстрактным классом.Профит может быть в полиморфизме.Зы. Ещё у меня там смайлик был.


Nechto

Сон Веры Павловны,2. Интерфейс чаще применяют для изменения поведения класса. А не данных класса.Но это все условно конечно.


Nechto

Здравствуйте!Подскажите пожалуйста, как сравнить значения свойств двух классов с разной структурой, но наследуемых один интерфейс?
public interface IA
{ 
 int Id { get; set; }
 string Name { get; set; }
}
public class A : IA
{ 
 public int Id { get; set; }
 public string Name { get; set; }
}
public class B : IA
{ 
 public int Id { get; set; }
 public string Name { get; set; }
 public string Test { get; set; }
}

IA c1 = new A (1, "1111");
IA c2 = new B (1, "1111", "2222");

if (c1 == c2) //Как правильно определить, что значения этих классов схожи относительно интерфейсов?
(c1 as IA).Equals(c2 as IA)ну и может понадобиться использование IEqualityComparer


Nechto

Сделал так, работает.
public static bool EqualsEntity<T>(this T obj, T entity) where T : class
{
 var objProps = typeof(T).GetProperties();
 var entP1 = obj.GetType().GetProperties();
 var entP2 = entity.GetType().GetProperties(); 
 foreach (var objP in objProps)
 {
 var p1 = entP1.FirstOrDefault(w => w.Name == objP.Name);
 var p2 = entP2.FirstOrDefault(w => w.Name == objP.Name);
 if (p1 != null && p2 != null)
 {
 var v1 = p1.GetValue(obj);
 var v2 = p2.GetValue(entity);
 if (!v1.Equals(v2))
 {
 return false;
 }
 }
 }
 return true;
}


Nechto

Nechto,Тормоза проверь на всякий.


Nechto

Nechto,нафига городить такое для сравнения 2 классов? я бы еще понял, если объекты были упакованы и сравнение происходило где во View, но типы известны и определены, такое сравнение будет работать на порядок, если не на несколько медленнее. я бы такой код в CodeReview не пропустил в продакшн


Nechto

Сон Веры Павловны,По ООП в коде выше делают класс Б наследником над классом А или оба класса над абстрактным классом.Профит может быть в полиморфизме.Зы. Ещё у меня там смайлик был.
Сон Веры Павловны,2. Интерфейс чаще применяют для изменения поведения класса. А не данных класса.Но это все условно конечно.
Это всё замечательно (и про всё это я в курсе), но это всё вообще не имеет никакого отношения к вопросу топикстартера. Может, еще поговорим про LOH? Или про интернирование строк? Так, чисто чтоб вопрос расширить.


Nechto

(c1 as IA).Equals(c2 as IA)
Без переопределенного Equals здесь будет просто проверка равенства ссылок (а они разные).


Nechto

Сон Веры Павловны,Ты так и не врубился что интерфейс придумал ТС?


Nechto

Roman Mejtes,+1ТС! Колись об исходной постановке. ОРМ?


Nechto

Roman Mejtes,+1ТС! Колись об исходной постановке. ОРМ?
А что тут делиться. Я пример опубликовал.У меня в программе производится много расчетов, для этого я решил создать тесты. Они используются для проверки, после измененний алгоритма расчета, на рассчитанных ранее данных в БД.


Nechto

тесты
псевдокод тестов.Это если есть желание обсуждать или тормозит твое решение.Удачи!


Nechto

А если так:
public interface IA
{
 int Id { get; set; }
 string Name { get; set; }

 bool Compare(IA obj);
}

public abstract class SomeClassName : IA
{
 public int Id { get; set; }

 public string Name { get; set; }

 public bool Compare(IA obj)
 {
 return Id == obj.Id && Name == obj.Name;
 }
}

public class A : SomeClassName
{
 
}
public class B : SomeClassName
{
 public string Test { get; set; }
}


Nechto

А если так:
public interface IA
{
 int Id { get; set; }
 string Name { get; set; }

 bool Compare(IA obj);
}

public abstract class SomeClassName : IA
{
 public int Id { get; set; }

 public string Name { get; set; }

 public bool Compare(IA obj)
 {
 return Id == obj.Id && Name == obj.Name;
 }
}

public class A : SomeClassName
{
 
}
public class B : SomeClassName
{
 public string Test { get; set; }
}
Человек понял что мне надо. Только я не хотел нагружать сущности абстрактными классами. К тому же в некоторых из них абстр классы уже используются.


Nechto

Человек понял что мне надо. Только я не хотел нагружать сущности абстрактными классами. К тому же в некоторых из них абстр классы уже используются.
public static class ClassExtensions
{
 public static bool Compare(this IA source, IA obj)
 {
 return source.Id == obj.Id && source.Name == obj.Name;
 }
}

public interface IA
{
 int Id { get; set; }
 string Name { get; set; }
}

public class A : IA
{
 public int Id { get; set; }
 public string Name { get; set; }
}
public class B : IA
{
 public int Id { get; set; }
 public string Name { get; set; }
 public string Test { get; set; }
}

...

IA c1 = new A
{
 Name = "qqqqq",
 Id = 1
};
IA c2 = new B
{
 Name = "wwww",
 Id = 2
};


Nechto

Заоверрайдить в обоих классах Equals/GetHashCode, в методах при удачной попытке приведения к интерфейсу сравнивать поля из интерфейса/вычислять хэшкод. Проверка на эквивалентность - методом Equals.P.S. Желательно, чтобы поля, участвующие в определении эквивалентности/хэшкода, были неизменяемыми - это в будущем спасет от труднопонимаемых и трудновылавливаемых косяков.


Nechto

Nechto,Сделайте их наследниками)