This question has already been answered:

How to compare two objects by value without directly writing a method to compare each value?

TableMain aa = new TableMain { id = 5 }; TableMain bb = new TableMain { id = 5 }; if (/* Что написать здесь? */) ... 

Marked as a duplicate by MSDN.WhiteKnight , Pavel Mayorov members. c # Aug 6 '18 at 12:43 pm

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • explain in more detail what exactly do you want to do? Override equals? Compare classes as structures? - tym32167
  • It is necessary to compare two objects of the class TableMain, according to their values. If I understand you correctly, then yes, compare them as structures. - Triblaid Ru
  • What does it mean to "compare by their meanings" - There is no such thing as a "class value". If you need your types to behave like structures, then create them with structures - tym32167
  • It was not correctly expressed, it is necessary to compare instances of the TableMain class, for example, to compare an instance of aa and bb for all its attributes (id ...), without writing a method for sorting strings. - Triblaid Ru
  • 3
    without writing a method (or without any other gestures) you cannot compare reference types as significant, out of the box there is nothing like that. - tym32167 9:22 pm

1 answer 1

You can do this with the help of reflection, but it is not fast, but you can create a method for comparison once and cache it. If you have a lot of such comparisons in the code, then this is not the worst option:

 static class ComparerEx { public static bool IsEqual<T>(this T obj1, T obj2) => ComparerImpl<T>.IsEqual(obj1, obj2); private class ComparerImpl<T> { static ComparerImpl() { var parameters = new[] { Expression.Parameter(typeof(T), "x"), Expression.Parameter(typeof(T), "y") }; Expression body = Expression.Constant(true, typeof(bool)); var memberTypes = new[] { MemberTypes.Field, MemberTypes.Property }; foreach (var member in typeof(T).GetMembers().Where(m => memberTypes.Contains(m.MemberType))) body = Expression.AndAlso(body, Expression.Equal( Expression.MakeMemberAccess(parameters[0], member), Expression.MakeMemberAccess(parameters[1], member))); var lambda = Expression.Lambda<Func<T, T, bool>>(body, parameters); //Console.WriteLine(lambda); IsEqual = lambda.Compile(); } public static readonly Func<T, T, bool> IsEqual; } } 

After that you can write something like:

 class A { public int Prop1 { get; set; } public string Prop2 { get; set; } public int Field1; } 

and

 var a1 = new A { Prop1 = 1, Prop2 = "1", Field1 = 11 }; var a2 = new A { Prop1 = 1, Prop2 = "1", Field1 = 11 }; var r = a1.IsEqual(a2); // вернет true Console.WriteLine(r); 
  • after words you can do it with the help of reflection, expecting to see only reflection, and not the assembly of the expression tree and its compilation :) - Grundy
  • Without caching, there would be only a reflection, however, there separately would have to write access to the fields and access to the properties, in Expressions, benefit, there is MakeMemberAccess ¯ \ _ (ツ) _ / ¯ - Andrey NOP
  • There, in principle, it was possible to get along with ordinary Property or Field expressions, depending on the classes themselves - Grundy