이 문서는 기계 번역을 이용하여 번역되었습니다. 문서를 영문으로 보려면 영문 확인란을 선택하세요. 마우스 포인터를 텍스트 위로 이동시켜 팝업 창에서 영문 텍스트를 표시할 수도 있습니다.
번역
영문

Object.GetHashCode 메서드 ()

 

게시 날짜: 2016년 11월

기본 해시 함수로 작동합니다.

네임스페이스:   System
어셈블리:  mscorlib(mscorlib.dll에 있음)

public virtual int GetHashCode()

반환 값

Type: System.Int32

현재 개체의 해시 코드입니다.

해시 코드를 삽입 하 고 같은 해시를 기반으로 컬렉션의 개체를 식별 하는 데 사용 되는 숫자 값은는 Dictionary<TKey, TValue> 클래스는 Hashtable 클래스 또는에서 파생 된 형식이 DictionaryBase 클래스입니다. GetHashCode 메서드 개체 같음 빠른 검사 해야 하는 알고리즘에 대 한이 해시 코드를 제공 합니다.

System_CAPS_note참고

해시 테이블의 해시 코드 사용 방법에 대 한 내용은 및 일부 추가 해시 코드 알고리즘에 대 한 참조는 Hash Function Wikipedia 항목입니다.

두 개체는 같은 반환 같은 해시 코드입니다. 그러나 반대는 성립 하지 않습니다: 서로 다른 (같지 않음) 개체는 동일한 해시 코드를 가질 수 있으므로 같은 해시 코드 개체 같음 의미 하지 않습니다. 또한.NET Framework의 기본 구현은 보장 하지 않습니다는 GetHashCode 메서드와이 메서드가 반환 다를 수 있습니다 32 비트 및 64 비트 플랫폼에서와 같은 플랫폼 및.NET Framework 버전 간의 값입니다. 이러한 이유로, 사용 하지 마십시오이 메서드의 기본 구현 고유한 개체 식별자로 해시를 위해. 두 개의 결과에서이 수행합니다.

  • 같은 해시 코드 개체 같음 의미는 가정 하지 않아야 합니다.

  • 하지 유지 하거나 응용 프로그램 도메인, 프로세스 및 플랫폼 간에 동일한 개체 해시 수 때문에 생성 된 응용 프로그램 도메인 외부 해시 코드를 사용 해야 합니다.

System_CAPS_warning경고

해시 코드는 효율적인 삽입 및 해시 테이블을 기반으로 하는 컬렉션에서 조회를 위한 것입니다. 해시 코드는 영구 값이 아닙니다. 이러한 이유로:

  • 해시 코드 값을 serialize 하거나 데이터베이스에 저장 하지 마십시오.

  • 키가 지정 된 컬렉션에서 개체를 검색 하는 키로 해시 코드를 사용 하지 마십시오.

  • 응용 프로그램 도메인 또는 프로세스 간에 해시 코드를 전송 하지 마십시오. 경우에 따라 프로세스별 또는 응용 프로그램 도메인 별로 해시 코드를 계산할 수 있습니다.

  • 암호화 된 강력한 해시 해야 할 경우 암호화 해시 함수에서 반환 된 값 대신 해시 코드를 사용 하지 마십시오. 파생 된 클래스를 사용 하 여 암호화 해시에 대 한는 System.Security.Cryptography.HashAlgorithm 또는 System.Security.Cryptography.KeyedHashAlgorithm 클래스입니다.

  • 두 개체가 같은지 여부를 결정 하는 해시 코드의 같음 여부 테스트 하지 마십시오. (같지 않은 개체에 동일한 해시 코드를 있을 수 있습니다.) 같은지 여부를 테스트 하려면 호출는 ReferenceEquals 또는 Equals 메서드.

GetHashCode 파생 된 형식에서 메서드를 재정의할 수 있습니다. 경우 GetHashCode 은 재정의 되지 않으면 해시 코드를 호출 하 여 참조 형식을 계산 되는 Object.GetHashCode 참조 하십시오; 자세한 내용은 참조는 개체에 대해 해시 코드를 계산 하는 기본 클래스의 메서드 기반 RuntimeHelpers.GetHashCode합니다. 즉, 두 개체는 ReferenceEquals 메서드 반환 true 동일한 해시 코드를 있는 합니다. 값 형식을 재정의 하지 않는 경우 GetHashCode, ValueType.GetHashCode 기본 클래스의 메서드 리플렉션을 사용 하 여 해당 형식의 필드의 값을 기반으로 해시 코드를 계산 합니다. 즉, 해당 필드는 같은 값이 값 형식에는 같은 해시 코드가 있습니다. 재정의 대 한 자세한 내용은 GetHashCode하십시오 "상속자 참고 사항" 섹션을 참조 하세요.

System_CAPS_warning경고

재정의 하는 경우는 GetHashCode 메서드를 재정의 해야 하는 또한 Equals, 그 반대의 합니다. 경우 재정의 된 Equals 메서드 반환 true 재정의 된 같음에 대 한 두 개체는 검사 될 때 GetHashCode 메서드는 두 개체에 대해 동일한 값을 반환 해야 합니다.

해시 테이블에서 키로 사용 되는 개체의 유용한 구현을 경우 제공 하지 않습니다 GetHashCode를 제공 하 여 해시 코드 공급자를 지정할 수 있습니다는 IEqualityComparer 의 오버 로드 중 하나를 구현은 Hashtable 클래스 생성자입니다.

호출 하는 경우는 GetHashCode 클래스의 메서드는 Windows 런타임, 재정의 하지 않는 클래스에 대 한 기본 동작을 제공 GetHashCode합니다. 이는 .NET Framework에서 Windows 런타임에 대해 제공하는 지원의 일부입니다(Windows 스토어 앱 및 Windows 런타임에 대한 .NET Framework 지원 참조). 에 있는 클래스는 Windows 런타임 상속 받지 않습니다 Object, 하 고 구현 하지는 GetHashCode합니다. 그러나 하기로 표시 ToString, Equals(Object), 및 GetHashCode 메서드 C# 또는 Visual Basic 코드에서 사용 하 고.NET Framework에서는 이러한 방법에 대 한 기본 동작을 제공 하는 경우.

System_CAPS_note참고

Windows 런타임C# 또는 Visual Basic에서 작성 된 클래스에서 재정의할 수는 GetHashCode 메서드.

상속자 참고 사항:

개체의 값에 해당 하는 숫자 (해시 코드)를 빠르게 생성 하는 해시 함수가 사용 됩니다. 해시 함수는 일반적으로 각 유형에 맞게 하 고 고유성을 위해 사용 해야 인스턴스 필드 중 하나 이상 입력으로 합니다. 정적 필드의 값을 사용 하 여 해시 코드를 계산할 수 해야 합니다.

파생 된 클래스에 Object, GetHashCode 메서드는 기본 클래스에 게 위임할 수 Object.GetHashCode() 파생된 클래스 참조 일치에 일치 여부를 정의 하는 경우에 구현 합니다. 기본 구현은 GetHashCode 참조에 대 한 형식으로 반환 된 것에 해당 하는 해시 코드를 반환 된 RuntimeHelpers.GetHashCode(Object) 메서드. 재정의할 수 GetHashCode 변경할 수 없는 참조 형식에 대 한 합니다. 일반적으로 변경할 수 있는 참조 형식에 대 한 재정의 해야 GetHashCode 경우에 해당:

  • 변경할 수 없는 필드의 해시 코드를 계산할 수 있습니다. 또는

  • 개체의 해시 코드를 사용 하는 컬렉션에 포함 되는 동안 변경할 수 있는 개체의 해시 코드를 변경 되지 않습니다 확인할 수 있습니다.

그렇지 않으면 해시 테이블에서 변경할 수 있는 개체를 옮기면 생각할 수 있습니다. 재정의 하려는 경우 GetHashCode 변경 가능한 참조 형식에 대 한 설명서를 수행 하는 형식의 사용자 개체는 해시 테이블에 저장 하는 동안 개체 값을 수정 하지 않아야 함을 명확 하 합니다.

값 형식에 대 한 ValueType.GetHashCode 리플렉션을 사용 하는 기본 해시 코드 구현을 제공 합니다. 성능 향상을 위해 재정의 하는 것이 좋습니다.

System_CAPS_note참고

자세한 내용과 다양 한 방법에에서 대 한 해시 코드를 계산 하는 예제에 대 한 "예" 섹션을 참조 하십시오.

해시 함수는 다음과 같은 속성이 있어야 합니다.

  • 두 개체 같음으로 비교 하는 경우는 GetHashCode 각 개체에 대 한 메서드는 같은 값을 반환 해야 합니다. 그러나 경우 두 개체를 동일한 것으로 비교 하지 않습니다는 GetHashCode 두 개체에 대 한 메서드를 다른 값을 반환할 필요가 없습니다.

  • GetHashCode 메서드는 개체에 대 한 개체의 반환 값을 결정 하는 개체 상태를 수정 하지 않으면으로 동일한 해시 코드를 일관성 있게 반환 해야 Equals 메서드. Note이 응용 프로그램의 현재 실행에 대해서만 true이 고 다른 해시 코드를 응용 프로그램을 다시 실행 하는 경우 반환 될 수 있습니다.

  • 최상의 성능을 위해 해시 함수는 균등 한 분포가 클러스터 과도 하 게 하는 입력을 포함 하 여 모든 입력에 대 한 생성 해야 합니다. 구현은 개체 상태를 작은 수정 해야 최상의 성능 얻으려면 해시 테이블에 대 한 결과 해시 코드를 큰 수정을 될 것입니다.

  • 해시 함수를 계산 하는 데 비용이 취소 해야 합니다.

  • GetHashCode 메서드 예외를 throw 하지 않아야 합니다.

구현 예를 들어는 GetHashCode 에서 제공 되는 String 클래스 동일한 문자열 값에 대해 동일한 해시 코드를 반환 합니다. 따라서 두 String 동일한 문자열 값을 나타내는 경우 개체는 동일한 해시 코드를 반환 합니다. 또한 메서드를 사용 하 여 모든 문자는 문자열에 입력 특정 범위에 클러스터 된 경우에 무작위 분포 된 출력을 생성 (예를 들어 여러 사용자가 할 수만 있는 낮은 128 자의 ASCII 문자를 포함 하는 문자열은 문자열에 65, 535 유니코드 문자를 사용할 수 있지만).

좋은 해시 함수는 클래스에서 제공 하는 해시 테이블에 해당 개체를 추가 하는 성능 크게 저하 될 수 있습니다. 해시 함수를 구현 하는 키가 있는 해시 테이블에서 요소를 검색 시간이 일정 (예: o (1) 작업). 해시 함수의 잘 구현 하는 해시 테이블 검색의 속도 해시 테이블에 있는 항목의 수에 비례 (예를 들어는 O (n) 작업, 여기서 n 은 해시 테이블에서 항목의 수)입니다. 악의적인 사용자는 다음과 같은 경우 해시 테이블에 종속 된 응용 프로그램의 성능을 상당히 저하 될 수 있습니다. 있는 충돌 수를 증가 하는 데이터를 입력할 수 있습니다.:

  • 경우 해시 함수는 자주 충돌을 생성 합니다.

  • 해시 테이블에 있는 개체의 경우 같은지 또는 약 서로 값이 있는 해시 코드를 생성 합니다.

  • 사용자가 입력 데이터의 해시 코드 계산 합니다.

재정의 하는 클래스를 파생 GetHashCode 도 재정의 해야 합니다 Equals 되도록 두 개체가 동일한 해시 코드입니다; 그렇지 않으면는 Hashtable 형식을 올바르게 작동 하지 않을 수 있습니다.

동일 하거나 보다 작은 범위에는 숫자 값에 대 한 해시 코드를 계산 하는 가장 간단한 방법 중 하나는 Int32 값 단순히 값을 반환 합니다. 다음 예제에서는 이러한 구현에 대 한는 Number 구조입니다.

using System;

public struct Number
{
   private int n;

   public Number(int value)
   {
      n = value;
   }

   public int Value
   {
      get { return n; }
   }

   public override bool Equals(Object obj)
   {
      if (obj == null || ! (obj is Number)) 
         return false;
      else
         return n == ((Number) obj).n;
   }      

   public override int GetHashCode()
   {
      return n;
   }

   public override string ToString()
   {
      return n.ToString();
   }
}

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      for (int ctr = 0; ctr <= 9; ctr++) {
         int randomN = rnd.Next(Int32.MinValue, Int32.MaxValue);
         Number n = new Number(randomN);
         Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode());
      }   
   }
}
// The example displays output like the following:
//       n =   -634398368, hash code =   -634398368
//       n =   2136747730, hash code =   2136747730
//       n =  -1973417279, hash code =  -1973417279
//       n =   1101478715, hash code =   1101478715
//       n =   2078057429, hash code =   2078057429
//       n =   -334489950, hash code =   -334489950
//       n =    -68958230, hash code =    -68958230
//       n =   -379951485, hash code =   -379951485
//       n =    -31553685, hash code =    -31553685
//       n =   2105429592, hash code =   2105429592

대부분의 경우 형식에 해시 코드를 생성에 참여할 수 있는 여러 개의 데이터 필드입니다. 사용 하 여 이러한 필드를 조합 하는 해시 코드를 생성 하는 한 가지 방법은 XOR (eXclusive OR) 다음 예제와 같이 작업 합니다.

using System;

// A type that represents a 2-D point.
public struct Point
{
    private int x;
    private int y;

    public Point(int x, int y)
    {
       this.x = x;
       this.y = y;
    }

    public override bool Equals(Object obj)
    {
       if (! (obj is Point)) return false;

       Point p = (Point) obj;
       return x == p.x & y == p.y;
    }

    public override int GetHashCode()
    { 
        return x ^ y;
    } 
} 

public class Example
{
   public static void Main()
   {
      Point pt = new Point(5, 8);
      Console.WriteLine(pt.GetHashCode());

      pt = new Point(8, 5);
      Console.WriteLine(pt.GetHashCode());
   }
}
// The example displays the following output:
//       13
//       13

앞의 예제 (n1, n2)에 대 한 동일한 해시 코드를 반환 합니다. (n2, n 1) 및 등과 바람직한 것 보다 더 많은 충돌을 생성할 수 있습니다. 솔루션의 수를 사용 하 여 이러한 경우에 해시 코드는 동일 합니다. 해시 코드를 반환 하는 것 하나는 Tuple 각 필드의 순서를 반영 하는 개체입니다. 다음 예제에서는 가능한 구현을 사용 하 여 Tuple<T1, T2> 클래스입니다. 하지만 인스턴스화하는 성능 오버 헤드는 Tuple 개체 해시 테이블에 많은 수의 개체를 저장 하는 응용 프로그램의 전반적인 성능에 큰 영향 수 있습니다.

using System;

public struct Point
{
    private int x;
    private int y;

    public Point(int x, int y)
    {
       this.x = x;
       this.y = y;
    }

    public override bool Equals(Object obj)
    {
       if (!(obj is Point)) return false;

       Point p = (Point) obj;
       return x == p.x & y == p.y;
    }

    public override int GetHashCode()
    { 
        return Tuple.Create(x, y).GetHashCode();
    } 
} 

public class Example
{
   public static void Main()
   {
        Point pt = new Point(5, 8);
        Console.WriteLine(pt.GetHashCode());

        pt = new Point(8, 5);
        Console.WriteLine(pt.GetHashCode());
   }
}
// The example displays the following output:
//       173
//       269

두 번째 대체 솔루션으로 비트를 두 개 이상의 연속 된 필드의 해시 코드 왼쪽-이동 하 여 개별 해시 코드를 가중치 포함 됩니다. 최적으로 삭제 되 고 대신 31 비트를 벗어나 이동 비트 주위 하지 않고 삭제 됩니다. 비트 왼쪽 시프트 연산자 C# 및 Visual Basic 모두에 의해는 무시 되는 이후 다음과 같은 왼쪽된 shift 잘림 메서드 만들기 필요 합니다.

public int ShiftAndWrap(int value, int positions)
{
    positions = positions & 0x1F;

    // Save the existing bit pattern, but interpret it as an unsigned integer.
    uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
    // Preserve the bits to be discarded.
    uint wrapped = number >> (32 - positions);
    // Shift and wrap the discarded bits.
    return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);
}

다음 예제에서는 다음 방법을 사용 하 여이 shift 잘림의 해시 코드를 계산 하는 Point 앞의 예제에 사용 되는 구조입니다.

using System;

public struct Point
{
    private int x;
    private int y;

    public Point(int x, int y)
    {
       this.x = x;
       this.y = y;
    }

    public override bool Equals(Object obj)
    {
       if (!(obj is Point)) return false;

       Point p = (Point) obj;
       return x == p.x & y == p.y;
    }

    public override int GetHashCode()
    { 
        return ShiftAndWrap(x.GetHashCode(), 2) ^ y.GetHashCode();
    } 

    private int ShiftAndWrap(int value, int positions)
    {
        positions = positions & 0x1F;

        // Save the existing bit pattern, but interpret it as an unsigned integer.
        uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
        // Preserve the bits to be discarded.
        uint wrapped = number >> (32 - positions);
        // Shift and wrap the discarded bits.
        return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);
    }
} 

public class Example
{
   public static void Main()
   {
        Point pt = new Point(5, 8);
        Console.WriteLine(pt.GetHashCode());

        pt = new Point(8, 5);
        Console.WriteLine(pt.GetHashCode());
   }
}
// The example displays the following output:
//       28
//       37 

유니버설 Windows 플랫폼
8 이후 사용 가능
.NET Framework
1.1 이후 사용 가능
이식 가능한 클래스 라이브러리
이식 가능한 .NET 플랫폼 에서 지원됨
Silverlight
2.0 이후 사용 가능
Windows Phone Silverlight
7.0 이후 사용 가능
Windows Phone
8.1 이후 사용 가능
맨 위로 이동
표시: