Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. .NET (Core and Framework)
  4. Collection<t>.IndexOf and overloaded ==</t>

Collection<t>.IndexOf and overloaded ==</t>

Scheduled Pinned Locked Moved .NET (Core and Framework)
saleshelp
15 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Adriaan Davel
    wrote on last edited by
    #1

    Ok, I've Googled myself silly... In my base class I overload the == operator (including GetHashCode, != and Equals) and when I do a customerA == customerB it works 100%, yet when I do a customersList.IndexOf(customerA) I always get -1 even though I can see a customer instance in the list that should return true in my overloaded operator, and when I place a break point in my operator overloader it stops when I do a ==, but it does not break when I do an IndexOf()... Help please...

    ____________________________________________________________ Be brave little warrior, be VERY brave

    N F A 3 Replies Last reply
    0
    • A Adriaan Davel

      Ok, I've Googled myself silly... In my base class I overload the == operator (including GetHashCode, != and Equals) and when I do a customerA == customerB it works 100%, yet when I do a customersList.IndexOf(customerA) I always get -1 even though I can see a customer instance in the list that should return true in my overloaded operator, and when I place a break point in my operator overloader it stops when I do a ==, but it does not break when I do an IndexOf()... Help please...

      ____________________________________________________________ Be brave little warrior, be VERY brave

      N Offline
      N Offline
      Not Active
      wrote on last edited by
      #2

      This method determines equality using the default equality comparer EqualityComparer(T).Default for T, the type of values in the list. (http://msdn.microsoft.com/en-us/library/e4w08k17.aspx[^]) You'll need to implement IEqualityComparer[^] in your base class


      only two letters away from being an asset

      A 1 Reply Last reply
      0
      • A Adriaan Davel

        Ok, I've Googled myself silly... In my base class I overload the == operator (including GetHashCode, != and Equals) and when I do a customerA == customerB it works 100%, yet when I do a customersList.IndexOf(customerA) I always get -1 even though I can see a customer instance in the list that should return true in my overloaded operator, and when I place a break point in my operator overloader it stops when I do a ==, but it does not break when I do an IndexOf()... Help please...

        ____________________________________________________________ Be brave little warrior, be VERY brave

        F Offline
        F Offline
        freakyit
        wrote on last edited by
        #3

        hi first what kind of type is your customer list ?? is it a generic list or just a arraylist containing objects?!? overload the customerlist operators too for correct comparing i would suggest :) greetz

        A 1 Reply Last reply
        0
        • A Adriaan Davel

          Ok, I've Googled myself silly... In my base class I overload the == operator (including GetHashCode, != and Equals) and when I do a customerA == customerB it works 100%, yet when I do a customersList.IndexOf(customerA) I always get -1 even though I can see a customer instance in the list that should return true in my overloaded operator, and when I place a break point in my operator overloader it stops when I do a ==, but it does not break when I do an IndexOf()... Help please...

          ____________________________________________________________ Be brave little warrior, be VERY brave

          A Offline
          A Offline
          Adriaan Davel
          wrote on last edited by
          #4

          Found the (strange) answer... ==, .Equals() and != works fine if you implement in the base object, but to be able to overload for Collection.IndexOf() you MUST implement IEquatable on the Customer object, not on the base... If this makes sense to anybody please explain to me as I'n jealous... PS: I'm working in Silverlight 3, please tell me this is not a SL 3 issue...

          ____________________________________________________________ Be brave little warrior, be VERY brave

          G 1 Reply Last reply
          0
          • N Not Active

            This method determines equality using the default equality comparer EqualityComparer(T).Default for T, the type of values in the list. (http://msdn.microsoft.com/en-us/library/e4w08k17.aspx[^]) You'll need to implement IEqualityComparer[^] in your base class


            only two letters away from being an asset

            A Offline
            A Offline
            Adriaan Davel
            wrote on last edited by
            #5

            Mark Nischalke wrote:

            You'll need to implement IEqualityComparer[^] in your base class

            Hi Mark, I found that implementing this in my base class did not give me what I needed, implementing it in my actual (child) class however gave me what I needed, does that make sense to you?

            ____________________________________________________________ Be brave little warrior, be VERY brave

            N 1 Reply Last reply
            0
            • F freakyit

              hi first what kind of type is your customer list ?? is it a generic list or just a arraylist containing objects?!? overload the customerlist operators too for correct comparing i would suggest :) greetz

              A Offline
              A Offline
              Adriaan Davel
              wrote on last edited by
              #6

              I'm using a ObservableCollection as generated for the Silverlight 3 Service in the Proxy...

              ____________________________________________________________ Be brave little warrior, be VERY brave

              1 Reply Last reply
              0
              • A Adriaan Davel

                Mark Nischalke wrote:

                You'll need to implement IEqualityComparer[^] in your base class

                Hi Mark, I found that implementing this in my base class did not give me what I needed, implementing it in my actual (child) class however gave me what I needed, does that make sense to you?

                ____________________________________________________________ Be brave little warrior, be VERY brave

                N Offline
                N Offline
                Not Active
                wrote on last edited by
                #7

                Show what you have done and maybe someone can give you advice.


                only two letters away from being an asset

                A 1 Reply Last reply
                0
                • N Not Active

                  Show what you have done and maybe someone can give you advice.


                  only two letters away from being an asset

                  A Offline
                  A Offline
                  Adriaan Davel
                  wrote on last edited by
                  #8

                  Its a rather elaborate thing, would have to create a new project to explain in one shot. Will have to try explain tomorrow, need to go now

                  ____________________________________________________________ Be brave little warrior, be VERY brave

                  1 Reply Last reply
                  0
                  • A Adriaan Davel

                    Found the (strange) answer... ==, .Equals() and != works fine if you implement in the base object, but to be able to overload for Collection.IndexOf() you MUST implement IEquatable on the Customer object, not on the base... If this makes sense to anybody please explain to me as I'n jealous... PS: I'm working in Silverlight 3, please tell me this is not a SL 3 issue...

                    ____________________________________________________________ Be brave little warrior, be VERY brave

                    G Offline
                    G Offline
                    Gideon Engelberth
                    wrote on last edited by
                    #9

                    I think I might be able to explain, but it depends on your current code. From reading your posts, you seem to have something like this:

                    public class Base : IEquatable<Base>
                    {
                    public static bool operator==(...)
                    {
                    ...
                    }

                    //other associated overrides
                    

                    }

                    public class Derived : Base
                    {
                    //no overrides in this class
                    }

                    The question is, do you have Collection<Base> or Collection<Derived>? If you use Reflector to dig through the EqualityComparer code, you will see that it checks for IEquatable<T> where T is the exact type of the collection. Thus, if you have a collection of Derived, I would expect you to need to implement IEquatable on Derived. Since you have only implemented IEquatable<Base>, the check for IEquatable<Derived> will fail and you will fall back to the default implementation. Though, if you overrode the Equals inherited from object, I would think it should get called from the default comparer.

                    A 1 Reply Last reply
                    0
                    • G Gideon Engelberth

                      I think I might be able to explain, but it depends on your current code. From reading your posts, you seem to have something like this:

                      public class Base : IEquatable<Base>
                      {
                      public static bool operator==(...)
                      {
                      ...
                      }

                      //other associated overrides
                      

                      }

                      public class Derived : Base
                      {
                      //no overrides in this class
                      }

                      The question is, do you have Collection<Base> or Collection<Derived>? If you use Reflector to dig through the EqualityComparer code, you will see that it checks for IEquatable<T> where T is the exact type of the collection. Thus, if you have a collection of Derived, I would expect you to need to implement IEquatable on Derived. Since you have only implemented IEquatable<Base>, the check for IEquatable<Derived> will fail and you will fall back to the default implementation. Though, if you overrode the Equals inherited from object, I would think it should get called from the default comparer.

                      A Offline
                      A Offline
                      Adriaan Davel
                      wrote on last edited by
                      #10

                      Hi Gideon, thanks, that explains why it works the way it does, but doesn't explain why it doesn't use == or .Equals() :) Not sure why there are so many ways to check equality... Or why .IndexOf() has to use IEquatable<Derived> when other methods does not... Anyway, thanks for the description, makes sense

                      ____________________________________________________________ Be brave little warrior, be VERY brave

                      S G 2 Replies Last reply
                      0
                      • A Adriaan Davel

                        Hi Gideon, thanks, that explains why it works the way it does, but doesn't explain why it doesn't use == or .Equals() :) Not sure why there are so many ways to check equality... Or why .IndexOf() has to use IEquatable<Derived> when other methods does not... Anyway, thanks for the description, makes sense

                        ____________________________________________________________ Be brave little warrior, be VERY brave

                        S Offline
                        S Offline
                        supercat9
                        wrote on last edited by
                        #11

                        I believe the C# operators like "==" are only visible to the C# compiler, and are not visible to the underlying .Net library. As for why there are so many different types of equality, I think the idea is that there are different 'qualities' of equality. For example, for some purposes, the string "ABC" may be regarded as equal to "abc" or even "åbç", while in others it must be regarded as different. I'm not sure the exact logic behind which functions are used where in .Net; I can certainly imagine that it would be useful to be able to specify a definition of equality which did not require two objects to have the same GetHashCode value (since such a value must be optimized for one particular definition of equality); I'm not sure whether any of the defined equality functions use such a definition.

                        G 1 Reply Last reply
                        0
                        • A Adriaan Davel

                          Hi Gideon, thanks, that explains why it works the way it does, but doesn't explain why it doesn't use == or .Equals() :) Not sure why there are so many ways to check equality... Or why .IndexOf() has to use IEquatable<Derived> when other methods does not... Anyway, thanks for the description, makes sense

                          ____________________________________________________________ Be brave little warrior, be VERY brave

                          G Offline
                          G Offline
                          Gideon Engelberth
                          wrote on last edited by
                          #12

                          There are so many ways to check equality because there are so many situations that need to be handled. Jared Parsons wrote a nice set of articles that explain some of this topic. The link is to the last article in the set, each of which links to the article before (in typical blog fashion). One reason to have more than just the operator is because the operator must be a static method. This means that which operator to call depends on the compile-time type of the variable instead of the using the runtime-type like a virtual method (such as Equals) would. Also, because they are static, operators cannot be defined on interfaces. So if you need equality methods on an interface, you have to have instance methods. An advantage of the IEqualityComparer interface is that you can have a different condition for "equality" in different situations for the same type. In one case, you may only check the name, but in another you may want to check both the name and the age. This would be impossible with just the operator or overriden virtual method, but is possible to do with the extra interface. (A similar reasoning can be given for having both IComparer and IComparable for sorting.) C# has a particularly nasty problem when it comes to == vs .Equals(). In C#, if you write if (a == b) { ... } when there is no overloaded operator for the types of variables a and b, the compiler will check to see if the are both references to the same object. In VB however, writing If a = b Then ... when there is no overloaded operator, a compile error will occur. To see if a and b are references to the same object, you use the Is and IsNot operators. Collection<Derived>.IndexOf has to use IEquatable<Derived> because it was written without any knowledge of what your classes will be. The alternative would involve a bunch of messy reflection code that would cause horrible performance and would probably not be useful in most situations. All the other places where you are using == and Equals, the compiler knows about and will use your methods since they are the best match. Out of curiosity, did you both implement the Equals for IEquatable<Base> and override the Equals from object?

                          public class Base : IEquatable<Base>
                          {
                          public static bool operator==(...)
                          {
                          ...
                          }

                          //this method is for IEquatable
                          pu
                          
                          L A 2 Replies Last reply
                          0
                          • S supercat9

                            I believe the C# operators like "==" are only visible to the C# compiler, and are not visible to the underlying .Net library. As for why there are so many different types of equality, I think the idea is that there are different 'qualities' of equality. For example, for some purposes, the string "ABC" may be regarded as equal to "abc" or even "åbç", while in others it must be regarded as different. I'm not sure the exact logic behind which functions are used where in .Net; I can certainly imagine that it would be useful to be able to specify a definition of equality which did not require two objects to have the same GetHashCode value (since such a value must be optimized for one particular definition of equality); I'm not sure whether any of the defined equality functions use such a definition.

                            G Offline
                            G Offline
                            Gideon Engelberth
                            wrote on last edited by
                            #13

                            Actually, the operators are visible to all languages. They are actually defined as methods with names such as op_Equality, op_Inequality, etc. and other languages can use their operators to call those methods. You are on the right track as far as qualities of equality, though strings are a weird case where there are quite a few different "levels" of equality. My response below explains what I see as reasons for different equality methods if you are interested.

                            1 Reply Last reply
                            0
                            • G Gideon Engelberth

                              There are so many ways to check equality because there are so many situations that need to be handled. Jared Parsons wrote a nice set of articles that explain some of this topic. The link is to the last article in the set, each of which links to the article before (in typical blog fashion). One reason to have more than just the operator is because the operator must be a static method. This means that which operator to call depends on the compile-time type of the variable instead of the using the runtime-type like a virtual method (such as Equals) would. Also, because they are static, operators cannot be defined on interfaces. So if you need equality methods on an interface, you have to have instance methods. An advantage of the IEqualityComparer interface is that you can have a different condition for "equality" in different situations for the same type. In one case, you may only check the name, but in another you may want to check both the name and the age. This would be impossible with just the operator or overriden virtual method, but is possible to do with the extra interface. (A similar reasoning can be given for having both IComparer and IComparable for sorting.) C# has a particularly nasty problem when it comes to == vs .Equals(). In C#, if you write if (a == b) { ... } when there is no overloaded operator for the types of variables a and b, the compiler will check to see if the are both references to the same object. In VB however, writing If a = b Then ... when there is no overloaded operator, a compile error will occur. To see if a and b are references to the same object, you use the Is and IsNot operators. Collection<Derived>.IndexOf has to use IEquatable<Derived> because it was written without any knowledge of what your classes will be. The alternative would involve a bunch of messy reflection code that would cause horrible performance and would probably not be useful in most situations. All the other places where you are using == and Equals, the compiler knows about and will use your methods since they are the best match. Out of curiosity, did you both implement the Equals for IEquatable<Base> and override the Equals from object?

                              public class Base : IEquatable<Base>
                              {
                              public static bool operator==(...)
                              {
                              ...
                              }

                              //this method is for IEquatable
                              pu
                              
                              L Offline
                              L Offline
                              Luc Pattyn
                              wrote on last edited by
                              #14

                              wow. there seems to be a lot hidden behind a simple == concept. I'll have to read your reply a couple more times. It does shed some light on this thread[^]. Thanks.

                              Luc Pattyn


                              Local announcement (Antwerp region): Lange Wapper? Neen!


                              1 Reply Last reply
                              0
                              • G Gideon Engelberth

                                There are so many ways to check equality because there are so many situations that need to be handled. Jared Parsons wrote a nice set of articles that explain some of this topic. The link is to the last article in the set, each of which links to the article before (in typical blog fashion). One reason to have more than just the operator is because the operator must be a static method. This means that which operator to call depends on the compile-time type of the variable instead of the using the runtime-type like a virtual method (such as Equals) would. Also, because they are static, operators cannot be defined on interfaces. So if you need equality methods on an interface, you have to have instance methods. An advantage of the IEqualityComparer interface is that you can have a different condition for "equality" in different situations for the same type. In one case, you may only check the name, but in another you may want to check both the name and the age. This would be impossible with just the operator or overriden virtual method, but is possible to do with the extra interface. (A similar reasoning can be given for having both IComparer and IComparable for sorting.) C# has a particularly nasty problem when it comes to == vs .Equals(). In C#, if you write if (a == b) { ... } when there is no overloaded operator for the types of variables a and b, the compiler will check to see if the are both references to the same object. In VB however, writing If a = b Then ... when there is no overloaded operator, a compile error will occur. To see if a and b are references to the same object, you use the Is and IsNot operators. Collection<Derived>.IndexOf has to use IEquatable<Derived> because it was written without any knowledge of what your classes will be. The alternative would involve a bunch of messy reflection code that would cause horrible performance and would probably not be useful in most situations. All the other places where you are using == and Equals, the compiler knows about and will use your methods since they are the best match. Out of curiosity, did you both implement the Equals for IEquatable<Base> and override the Equals from object?

                                public class Base : IEquatable<Base>
                                {
                                public static bool operator==(...)
                                {
                                ...
                                }

                                //this method is for IEquatable
                                pu
                                
                                A Offline
                                A Offline
                                Adriaan Davel
                                wrote on last edited by
                                #15

                                Hi Gideon, Thanks for the explination, I think I fully understand it now, but I will do more reading on it. All I did was to override == and Equals in my base class (which obviously did not give me the correct behaviour), then after much searching I implemented IEquatable<Derived> on my derived class and it worked fine so I stopped working on it. Should I try to implement IEquatable<Base> and see if that gives the correct behaviour? (The attributes I'm comparing on is part of the Base, infact I use the overloaded == to compare)

                                ____________________________________________________________ Be brave little warrior, be VERY brave

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups