AD

More Effective C # - Detailed Analysis Method GetHashCode

GetHashCode function normally in operation HashTable or Dictionary of the class when the data set is called, aims to produce a Key, for the convenience of the HashTable or Dictionary search. Each type, regardless of a value type or reference type, provide this basic function, can also function as override ToString or Equals as to override it. However, override this function is not recommended, but this function also requires the use of extra care.

For GetHashCode is to meet the following three points, this is a GetHashCode function to judge the validity of the standard.

First, the two equal objects, by the result of GetHashCode function to equal, in addition to the two objects are not equal, the return value by GetHashCode Otherwise equal; otherwise, through its produce HashCode and the data stored in the HashTable can not get out.

Second, for a type of object, its return value GetHashCode should be consistent from beginning to end. Otherwise, and as the first point.

Third, the GetHashCode function need to provide a good hash function, that is, within the minimum to achieve the data dispersion, the dispersion of the decision in other words it HashTable access efficiency.

For reference types GetHashCode function that comes with it, is basically correct, but not efficient; and the value of the type that comes GetHashCode function is basically incorrect, even if the right is also inefficient.

Let me talk about GetHashCode function reference type that comes with realization. 1. Net program will run when the object reference type tag, roughly similar to the following operations: marking the start to 0, when creating a reference type object when the tag will automatically add one object tag does not do so after release by an operation, this bit of self-increase as the database field.

This is why the GetHashCode function reference type is basically the right reasons. For the first, if the type does not override Equals or Operator == function, then type the Equals function comes only in the object reference layer for authentication, that is, an object is equal to another object or the object on another note reference to an object or another object is the object. This shows that there is no new reference to the object created, then when the reference mark does not change, it is meet for the first (if you override Equals or if the Operator == function, then appropriate to provide this version of the GetHashCode function This is carried out in the back narrative). As to the second, because the object data members of the change will not affect the reference mark of the change, so the second is also satisfied. For the third point, because the reference mark relative to the process as a whole, not specific to the type, it is not efficient is self-evident.

Then for a value type that comes with it GetHashCode function, more fun, in order to explain it more graphically interesting, please see the following code, guess what Debug output.

public struct ErrorMessage
{
        private string strMsg;
        private int nErrorCode;
        private DateTime dtInvoked;
        public bool TestHashCode()
        {
            return this.GetHashCode() == strMsg.GetHashCode();
        }

}
 // Test "GetHashCode" function in value type
 ErrorMessage err = new ErrorMessage( "Test", 0 );
 if( err.TestHashCode() )
        Debug.WriteLine( "Both hash code equal!" );
else
         Debug.WriteLine( "Not equal!" );

No one thought possible, Debug the output is "Both hash code equal!". Why? The reason is simple, the value type's GetHashCode is its own first member of the GetHashCode value as its return value. For the first, the two equal value type object, its the GetHashCode function return value is equal, it was no problem; but for the two objects are not equal, the GetHashCode they are likely to equal the return value. Clear violation of Article. For the second, because the value type of GetHashCode return value equal to the first member of the GetHashCode function value, then modify the value of the first member, also indirectly modify the object's GetHashCode value, which is also for consistency not satisfied. As to the third, the function itself, the efficiency is essentially the same and reference types, no use of special algorithms, so want to get better efficiency is impossible.

Here to talk about how to achieve a more accurate GetHashCode function how to avoid the above error (mentioned here before the two can achieve major meet, the last one involves the Hash function algorithms discussed here do not do).

The first talk about the value type, because the basic value type itself is incorrect. If you do not want to deal too much, after all, a good hash function is not easy, then the value type of GetHashCode from the laws of that element from the type of self-starting. For a value type, if the existence of its own uniquely identify a data object of this type, a bit like the Key field in the database, then use it as the first element type. For example, said before the ErrorMessage is, dtInvoked members said that the only type of data, it can be modified as follows. This satisfied the first validation, for the second is to ensure that this type of an object through the same throughout GetHashCode can, we must prevent the first member is modified, the better approach is to mark it with readonly, then the more complete style should be as follows. This type of GetHashCode for the ErrorMessage is at least correct. Some people say, if the type is not defined as a single member can be the only mark, then I suggest you not to this type of data to generate Key.

public struct ErrorMessage
{
      private readonly DateTime dtInvoked;

       private string strMsg;

        private int nErrorCode;
}

Then talk about the GetHashCode function for reference types rewritten. For the first, in reference types are likely to rewrite the Equals function, then the type that comes GetHashCode function can not meet this requirement, the need for rewriting to adapt to this change. How easy to rewrite the GetHashCode function to achieve the effect of it, where you can continue to use the previous value of the type of approach that one can choose the members of that uniquely identifies the object to generate HashCode, while members of being modified to avoid this.

For example, a reference to a more reasonable type of GetHashCode function as follows (in this case applied to the original book):

public class Customer

(

private readonly string _name;

private decimal _revenue;

public Customer (string name): this (name, 0)

(

)

public Customer (string name, decimal revenue)

(

_name = name;

_revenue = revenue;

)

/ / / <summary>

/ / / Name property which only can be accessed in reading mode

/ / / </ Summary>

public string Name

(

get (return _name;)

)

/ / / <summary>

/ / / Create a new object with new name

/ / / </ Summary>

/ / / <param Name="newName"> </ param>

/ / / <returns> </ Returns>

public Customer ChangeName (string newName)

(

return new Customer (newName, _revenue);

)

/ / / <summary>

/ / / Customer hash code generated by name

/ / / </ Summary>

/ / / <returns> </ Returns>

public override int GetHashCode ()

(

return _name.GetHashCode ();

)

)

For Customer type object, it's HashCode is determined by its members _name, so can not be easily changed, if by calling ChangeName method to replace the original object when the first operation to HashTable, first delete the original, created after a new save. As follows:

Customer c1 = new Customer ("test1");

object orders = new object ();

myHashTable.Add (c1, orders);

/ / Change name

Customer c2 = c1.ChangeName ("test2");

object o = myHashTable [c1];

myHashTable.Remove (c1);

myHashTable.Add (c2, o);

For the above objects in Custemer is just to generate the object stored in the HashTable in the HashCode, of course, in practice, the two need to associate, or save the data using HashTable not have any meaning.

So for value types and reference types GetHashCode rewrite the basic over this, apparently above the rewrite, just to ensure that the correct type of GetHashCode, but for its efficiency has not been great progress, or other words, rewrite GetHashCode function is retained after the HashTable efficiency is not high. How to use the GetHashCode function better hash function to generate the HashCode has good distribution, I will not discuss it, because this issue is enough light to write several books.

For the GetHashCode function, generally have to stop here, and finally to enhance memory, to sum up.

First of all, do not override this function in the case, this is mainly talk about the use of which should be noted.

1. Does not recommend the use of a value type object GetHashCode function return value to a HashTable object Key;

2. Reference type can be used, but be aware that if the override of the Equals function, be sure to override the GetHashCode function to achieve the same;

Besides that override this function requires attention.

1. Whether a value type or reference type, to ensure that members can not be produced HashCode modified;

2. For members produce HashCode modified to produce a new object to be processed, while the use of side be amended accordingly, that is, adding the first delete the old new.

GetHashCode a subtle use of type of risk, so use the time to special attention.
标签: override, object reference, efficiency, tostring, convenience, object tag, database field, hashtable, realization, hashcode, hash function, dispersion, validity, aims, dictionary search, type tag, extra care
分类: DotNet
时间: 2010-06-03

相关文章

  1. Detailed analysis with Squid reverse proxy method to achieve

    from http://tech.ccidnet.com/art/737/20070417/1063859_1.html Detailed analysis with Squid reverse proxy method ...
  2. UI interface design requirements analysis method

    UI interface design requirements analysis method This article is from: WWW.51UI.CN An interface requirements a ...
  3. Android GSM drive module (rild) detailed analysis of (a) basic structure and initialization

    Android GSM Drive Module (rild) detailed analysis of (a) basic structure and initialization Panda brother and ...
  4. Android GSM drive module (rild) detailed analysis of (b) request process

    Android GSM drive module (rild) detailed analysis of (b) request process Panda brother published in IT168 and ...
  5. Android GSM drive module (rild) detailed analysis of (c) response process

    Android GSM drive module (rild) detailed analysis of (c) response processes Panda brother published in IT168 a ...
  6. PS command Linux operating system, detailed analysis

    PS command Linux operating system, detailed analysis To monitor and control processes in the system, with the ...
  7. Fully instantiated WebService detailed analysis

    Fully instantiated WebService detailed analysis 2010-12-19 21:47:08 Source: gjrencai.com View: 957 times First ...
  8. Linux operating system commands detailed analysis PS

    Linux operating system commands detailed analysis PS To monitor the process control system, use the ps command ...
  9. Detailed analysis of 14 kinds of software testing types

    Detailed analysis of 14 kinds of software testing types
  10. RDP protocol detailed analysis (1)

    RDP protocol detailed analysis 1 Introduction 2 Overview Three of a Kind Contact level 4 shows the connection ...
  11. RDP protocol detailed analysis (5)

    Five functional modules Description: Mission marks Note: applies to all non-graphics-channel data. 00 00 00 00 ...
  12. MySQL grant syntax detailed analysis

    The following article is the MySQL grant syntax detailed analysis, if you are related to the MySQL grant synta ...
  13. [Transfer] svnserve configuration file detailed analysis

    svnserve is a light that comes with SVN server, the client by using the svn: / / or svn + ssh: / / prefix the ...
  14. oracle job and the job does not run using the Detailed inspection method (reproduced)

    oracle job and the job does not run using the Detailed screening method 1 point per day sample implementation ...
  15. [Reserved] MYSQL in SQL performance analysis method for a detailed explanation Explain

    I. Grammar explain <table_name> For example: explain select * from t3 where Two. Explain the Output Inte ...
  16. Nutch Crawler workflow and detailed analysis of file formats

    Nutch is divided into two parts: the crawler crawler and query searcher. Crawler is mainly used to grab pages ...
  17. Add a version for the program auto-update feature (transfer + detailed analysis)

    OverView: Program through the background check for the latest version of the day, if need to update the curren ...
  18. Detailed analysis of three ORACLE lock mechanism

    ORACLE locking mechanism is mainly to control the concurrent operation, to ensure data consistency and accurac ...
  19. [Android2D game development of ten] (optimized) a detailed analysis of the efficiency of Android Traceview viewer! Analysis program running speed;

    Since I am now a full-time doing online games company, so now need to use some method of operation of online g ...