2

I have two classes and their variables are exactly the same.(To avoid prolonging the question, I don't explain why I'm using the same class.) I am comparing the same variables in these two classes with Reflection. The function returns true if there is a variable whose value has changed.. However, this function I wrote does not make the comparison correctly if there is a list in the class. Returns true for identical and unchanged lists, but the result should be false

Assume the list is full and the same values

CLASS ONE CLASS TWO
ID = 5 ID = 5
Number = 10 Number = 10
List a List a
 private bool Compare(Class A, Class B)
        {
            A.GetType().GetProperties().ToList().ForEach(p =>
            {
                B.GetType().GetProperties().ToList().ForEach(p2 =>
                {
                    if (p.Name == p2.Name)
                    {

                        if
                         (!p.GetValue(A).Equals(p2.GetValue(B)))
                        {
                            result = true;
                        }


                    }
                } 
                );
            });

            return result;
        }
sitera
  • 39
  • 6
  • Why true if not equal? – Rand Random Aug 28 '22 at 14:38
  • 1
    Wait, you start with saying thaty you are using two classes, then you are saying (in parantheses) that you are using the same class. Then, once more again, you are talking about two classes. But then in your code example you are showing that you try to compare two instances of only the _same_ class. Color me utterly confused about what you are trying to explain here. Please make up your mind... –  Aug 28 '22 at 14:40
  • You may want to consider implementing https://learn.microsoft.com/en-us/dotnet/api/system.iequatable-1?view=net-6.0 – Christoph Lütjen Aug 28 '22 at 14:40
  • And records could be something helpful here: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records – Christoph Lütjen Aug 28 '22 at 14:43
  • @MySkullCaveIsADarkPlace , The names of the classes are different, but the variables inside are the same. – sitera Aug 28 '22 at 14:45
  • @sitera, then why do you talk about "using the same class"? Then why is your code example only comparing two instances of one and the same class? Your code example simply does not deal with two classes. How do you expect people to help you when your explanations and your code example contradict each other? I would suggest you edit your question in a way so that it makes it clear what you are actually asking about without contradictions. –  Aug 28 '22 at 14:49
  • Worth reading: https://github.com/GregFinzer/Compare-Net-Objects/wiki/Getting-Started (nuget lib, that should do what you're looking for), https://stackoverflow.com/questions/506096/comparing-object-properties-in-c-sharp (code examples) – Christoph Lütjen Aug 28 '22 at 14:50
  • "_Returns true for identical and unchanged lists, but the result should be false_". So the result should be false even though the lists in A and B are identical and unchanged? In which case then should the result be true? –  Aug 28 '22 at 14:56
  • @ MySkullCaveIsADarkPlace , Calm down, if you're really trying to help and you don't understand what I wrote, you can look at the image and the code. – sitera Aug 28 '22 at 14:57
  • I did and i do not understand. But hey, i leave you to your business then, if you partout don't like to clarify the contradictions and ambiguities in your Q. I was trying to help, but i can't because so little makes sense in your question. But hey, i never had and still don't have any problems walking away from other people's problems. Good luck. –  Aug 28 '22 at 14:59
  • @MySkullCaveIsADarkPlace , I did not want to hurt you. You're just overreacting – sitera Aug 28 '22 at 15:05
  • @sitera, don't worry, i am not hurt. I was trying to understand your problem. I told you about the contradictions i see in your question. Your response was that i should look at your question (that is still unchanged). I still see the very same things i saw that led me to write my first and following comments. There is nothing further for me to do here. I am still understanding as much -- or rather as little about your problem as i did when writing my 1st comment. I am not hurt, i am just at the end of the road with respect to your problem. There is nothing emotional about this at all... –  Aug 28 '22 at 15:10
  • @–MySkullCaveIsADarkPlace Okey – sitera Aug 28 '22 at 15:19
  • Like @MySkullCaveIsADarkPlace, I'm confused by `bool Compare(Class A, Class B)` and your statement _"I have two classes and their variables are exactly the same."_. I'm guessing you mean to say _"Properties"_ and not _"Variables"_, but I don't have a clue about you two classes statement. Your calls to `ToList` after `GetProperties` is both superfluous and expensive (it copies the array that is returned into a newly constructed list) – Flydog57 Aug 28 '22 at 18:19
  • The "value" of the list property is the **reference** (think: address) of the list object in memory. So the reflection code is only checking whether those two reference addresses are the same. **This is true for any reference type you may have as a member**. A better strategy to resolve this issue to actually implement an [`IComparer`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.icomparer?view=net-6.0) and [`IEquatable`](https://learn.microsoft.com/en-us/dotnet/api/system.iequatable-1?view=net-6.0) between your two types. – Joel Coehoorn Aug 29 '22 at 16:36
  • Also, it's **VERY IMPORTANT** to understand and clearly communicate the difference between using two classes and using two instances of the same class type. Those are _not the same thing_, but the question text uses them interchangeably, and is therefore confusing. The same is true for the difference between the value of an object and variable that refers to the object. These are different concepts, but the question text uses them interchangeable, therefore resulting in an unclear question that is harder to answer. – Joel Coehoorn Aug 29 '22 at 16:39

1 Answers1

0

First, I recommend that you implement IEquatable https://learn.microsoft.com/en-us/dotnet/api/system.iequatable-1?view=net-6.0.

Then, it's hard to be 100% sure, but your problement is probably that return true when the values are not equal.

Finally, your problem with the lists is probably because equality with lists are using the reference to the list not the values contained by them.

Since you're using reflexion I don't think it's best to handle the list case explicitly. One way to do it would be to do a wrapper class that implements the Equals() method with something like this :

if (listA.Except(listB).Any())

https://stackoverflow.com/a/9524717/12330678

TOOL
  • 70
  • 1
  • 10
  • Yes, it should be true when the values ​​are not equal. (Finally, your problem with the lists is probably because equality with lists are using the reference to the list not the values contained by them ) Do you have a code solution to this comment? – sitera Aug 28 '22 at 15:40
  • @sitera I've updated my answer to have one way to handle lists, but I'm not sure what the best way to do it, it's hard to know what you're really trying to to with your two classes in the first place. – TOOL Aug 29 '22 at 16:28