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. C#
  4. GetHashCode override for a value wrapper. Is mutable ok?

GetHashCode override for a value wrapper. Is mutable ok?

Scheduled Pinned Locked Moved C#
csharplinqcryptographyquestion
6 Posts 4 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.
  • G Offline
    G Offline
    GParkings
    wrote on last edited by
    #1

    Hi all, I am in the process of coding a generic wrapper class that adds some metadata and functionality to a generic value (unconstrained). I would prefer the equality of this wrapper to simply pass through to the underlying value. As a result the equals and getHashCode overrides are as follows

    public override bool Equals(object obj)
    {
    return _value.Equals(obj);
    }

    public override int GetHshCode()
    {
    return _value.GetHashCode();
    }

    My concern here is that, as _value is not read-only, we now have a hash code that could potentially change. Am i right to be concerned about this with regard to housing the class within collections or using it within LINQ statements? (IIRC they make use of hashtables behind the scenes) Is there a better/safer approach? Thanks in advance

    Pedis ex oris Quidquid latine dictum sit, altum sonatur

    B P 2 Replies Last reply
    0
    • G GParkings

      Hi all, I am in the process of coding a generic wrapper class that adds some metadata and functionality to a generic value (unconstrained). I would prefer the equality of this wrapper to simply pass through to the underlying value. As a result the equals and getHashCode overrides are as follows

      public override bool Equals(object obj)
      {
      return _value.Equals(obj);
      }

      public override int GetHshCode()
      {
      return _value.GetHashCode();
      }

      My concern here is that, as _value is not read-only, we now have a hash code that could potentially change. Am i right to be concerned about this with regard to housing the class within collections or using it within LINQ statements? (IIRC they make use of hashtables behind the scenes) Is there a better/safer approach? Thanks in advance

      Pedis ex oris Quidquid latine dictum sit, altum sonatur

      B Offline
      B Offline
      BobJanova
      wrote on last edited by
      #2

      This could, I think, potentially cause problems if you're using instances of this class in the key of dictionaries. But no more so than if you put _value in there instead, and there's not really a way to avoid it with mutable types. I think that you are only going to be sacrificing a bit of performance, not creating subtle bugs, because the .Net hashtable will look through all the items if it doesn't get a hash hit. Generally, you wouldn't put mutable things into collections as a key anyway. There are only two 'golden rules' of GetHashCode, to quote the documentation[^]:

      If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values. The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method. Note that this is true only for the current execution of an application, and that a different hash code can be returned if the application is run again.

      You generally want to use as much of the state (which you compare within an Equals override) as possible to make the hash code uniqueness work well, and that means that if you mutate the object you change its hash code, which could cause a minor slowdown next time you look 'it' (i.e. something that matches it by Equals) up. So in conclusion, you're okay, but good question, and it's good practice not to mutate things (at least, not to mutate the parts of them which are part of their equality semantics) if they're being used as dictionary keys.

      G D 2 Replies Last reply
      0
      • B BobJanova

        This could, I think, potentially cause problems if you're using instances of this class in the key of dictionaries. But no more so than if you put _value in there instead, and there's not really a way to avoid it with mutable types. I think that you are only going to be sacrificing a bit of performance, not creating subtle bugs, because the .Net hashtable will look through all the items if it doesn't get a hash hit. Generally, you wouldn't put mutable things into collections as a key anyway. There are only two 'golden rules' of GetHashCode, to quote the documentation[^]:

        If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values. The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method. Note that this is true only for the current execution of an application, and that a different hash code can be returned if the application is run again.

        You generally want to use as much of the state (which you compare within an Equals override) as possible to make the hash code uniqueness work well, and that means that if you mutate the object you change its hash code, which could cause a minor slowdown next time you look 'it' (i.e. something that matches it by Equals) up. So in conclusion, you're okay, but good question, and it's good practice not to mutate things (at least, not to mutate the parts of them which are part of their equality semantics) if they're being used as dictionary keys.

        G Offline
        G Offline
        GParkings
        wrote on last edited by
        #3

        Excellent explanation. Thanks for putting my mind at ease :D

        Pedis ex oris Quidquid latine dictum sit, altum sonatur

        1 Reply Last reply
        0
        • G GParkings

          Hi all, I am in the process of coding a generic wrapper class that adds some metadata and functionality to a generic value (unconstrained). I would prefer the equality of this wrapper to simply pass through to the underlying value. As a result the equals and getHashCode overrides are as follows

          public override bool Equals(object obj)
          {
          return _value.Equals(obj);
          }

          public override int GetHshCode()
          {
          return _value.GetHashCode();
          }

          My concern here is that, as _value is not read-only, we now have a hash code that could potentially change. Am i right to be concerned about this with regard to housing the class within collections or using it within LINQ statements? (IIRC they make use of hashtables behind the scenes) Is there a better/safer approach? Thanks in advance

          Pedis ex oris Quidquid latine dictum sit, altum sonatur

          P Offline
          P Offline
          PIEBALDconsult
          wrote on last edited by
          #4

          Then make it immutable / readonly; it probably should be anyway.

          G 1 Reply Last reply
          0
          • P PIEBALDconsult

            Then make it immutable / readonly; it probably should be anyway.

            G Offline
            G Offline
            GParkings
            wrote on last edited by
            #5

            can't make it readonly im afraid. The class is providing a solution to firing off propertyChanged notifications without having to rely on hardcoded property name strings (it provides a 'single run per property' means by which property names are programatically derived) As a result the wrapper class is being used in place of a basic property backing field and therefore must be able to have its value changed as and when required. hope that makes sense

            Pedis ex oris Quidquid latine dictum sit, altum sonatur

            1 Reply Last reply
            0
            • B BobJanova

              This could, I think, potentially cause problems if you're using instances of this class in the key of dictionaries. But no more so than if you put _value in there instead, and there's not really a way to avoid it with mutable types. I think that you are only going to be sacrificing a bit of performance, not creating subtle bugs, because the .Net hashtable will look through all the items if it doesn't get a hash hit. Generally, you wouldn't put mutable things into collections as a key anyway. There are only two 'golden rules' of GetHashCode, to quote the documentation[^]:

              If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values. The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method. Note that this is true only for the current execution of an application, and that a different hash code can be returned if the application is run again.

              You generally want to use as much of the state (which you compare within an Equals override) as possible to make the hash code uniqueness work well, and that means that if you mutate the object you change its hash code, which could cause a minor slowdown next time you look 'it' (i.e. something that matches it by Equals) up. So in conclusion, you're okay, but good question, and it's good practice not to mutate things (at least, not to mutate the parts of them which are part of their equality semantics) if they're being used as dictionary keys.

              D Offline
              D Offline
              Daniel Grunwald
              wrote on last edited by
              #6

              BobJanova wrote:

              I think that you are only going to be sacrificing a bit of performance, not creating subtle bugs, because the .Net hashtable will look through all the items if it doesn't get a hash hit.

              No, it won't. Mutating an object that is used as a dictionary key will cause bugs. The correct solution is to remove the object from the dictionary, then mutate the key, then re-add it. Or better, just make the key immutable, remove the object from the dictionary, and re-add it using another key.

              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