Metodo Object.GetHashCode (System)

Cambia visualizzazione:
ScriptFree
Riferimento a .NET Framework
Metodo Object.GetHashCode
Il presente articolo è stato tradotto manualmente. Per visualizzare questa pagina e contemporaneamente visualizzarne il contenuto in lingua inglese, passare alla visualizzazione semplificata.

Funge da funzione hash per un determinato tipo.

Spazio dei nomi:  System
Assembly:  mscorlib (in mscorlib.dll)
Sintassi

Visual Basic
Public Overridable Function GetHashCode As Integer
C#
public virtual int GetHashCode()
Visual C++
public:
virtual int GetHashCode()
F#
abstract GetHashCode : unit -> int 
override GetHashCode : unit -> int 

Valore restituito

Tipo: System.Int32
Codice hash per l'oggetto Object corrente.
Note

Un codice hash è un valore numerico utilizzato per identificare un oggetto durante il test di uguaglianza. Può servire anche come indice per un oggetto in un insieme.

Il metodo GetHashCode può essere utilizzato in algoritmi di hash e strutture di dati, ad esempio una tabella hash.

L'implementazione predefinita del metodo GetHashCode non garantisce che i valori restituiti siano univoci per oggetti diversi. Inoltre, .NET Framework non garantisce l'implementazione predefinita del metodo GetHashCode e il valore restituito sarà identico nelle diverse versioni di .NET Framework. Di conseguenza, l'implementazione predefinita di questo metodo non deve essere utilizzata come identificatore di oggetto univoco per generare un hash.

Il metodo GetHashCode può essere sottoposto a override da un tipo derivato. I tipi di valori devono eseguire l'override di questo metodo per fornire una funzione hash che sia appropriata per il tipo e che garantisca una distribuzione utile in una tabella hash. Per univocità, il codice hash deve essere basato sul valore di una proprietà o un campo di un'istanza, anziché di una proprietà o un campo static.

Gli oggetti utilizzati come chiave in un oggetto Hashtable devono inoltre eseguire l'override del metodo GetHashCode perché devono generare il proprio codice hash. Se un oggetto utilizzato come chiave non fornisce un'implementazione utile del metodo GetHashCode, è possibile specificare un provider di codice hash quando si costruisce l'oggetto Hashtable. Nelle versioni di .NET Framework precedenti alla 2.0, il provider di codice hash è basato sull'interfaccia System.Collections.IHashCodeProvider. A partire dalla versione 2.0, il provider di codice hash è basato sull'interfaccia System.Collections.IEqualityComparer.

Note per gli implementatori

Una funzione hash è utilizzata per generare rapidamente un numero, o codice hash, che corrisponde al valore di un oggetto. Le funzioni hash sono in genere specifiche di ciascun Type e, per univocità, devono utilizzare come input almeno uno dei campi dell'istanza.

Una funzione hash deve presentare le seguenti proprietà:

  • Se due oggetti confrontati risultano uguali, il metodo GetHashCode per ogni oggetto dovrà restituire lo stesso valore. Tuttavia, se due oggetti confrontati non risultano uguali, i metodi GetHashCode per i due oggetti non dovranno restituire valori diversi.

  • Il metodo GetHashCode per un oggetto deve restituire coerentemente lo stesso codice hash finché lo stato dell'oggetto non viene modificato in modo da determinare il valore restituito del metodo Equals dell'oggetto. Si noti che ciò vale solo per l'esecuzione corrente di un'applicazione e che può essere restituito un codice hash diverso se l'applicazione viene eseguita nuovamente.

  • Per ottenere le migliori prestazioni, una funzione hash deve generare una distribuzione casuale per tutti gli input.

Ad esempio, l'implementazione del metodo GetHashCode fornita dalla classe String restituisce codici hash identici per valori stringa identici. Di conseguenza, due oggetti String restituiscono lo stesso codice hash se rappresentano lo stesso valore stringa. Il metodo utilizza inoltre nella stringa tutti i caratteri per generare un output ragionevolmente distribuito in modo casuale, anche quando l'input è suddiviso in cluster in alcuni intervalli. Molti utenti possono, ad esempio, avere stringhe contenenti soltanto i 128 caratteri ASCII inferiori, anche se una stringa può contenere qualsiasi dei 65.535 caratteri Unicode.

Nel caso delle classi derivate di Object, il metodo GetHashCode può delegare l'implementazione di Object.GetHashCode, se e soltanto se tale classe derivata definisce che l'uguaglianza di valori sia uguaglianza di riferimenti e che il tipo non è un tipo di valore.

Fornire una buona funzione hash su una classe può influire in modo significativo sull'aggiunta di tali oggetti a una tabella hash. In una tabella hash con una buona implementazione di una funzione hash, la ricerca di un elemento può richiedere tempo costante, ad esempio, un'operazione O(1). In una tabella hash con una scarsa implementazione di una funzione hash, le prestazioni di una ricerca dipendono dal numero di elementi presenti nella tabella hash, ad esempio, un'operazione O( n ), dove n è il numero di voci presenti nella tabella hash. L'elaborazione delle funzioni hash, inoltre, non dovrebbe risultare dispendiosa.

Le implementazioni del metodo GetHashCode non devono produrre riferimenti circolari. Se ad esempio ClassA.GetHashCode chiama ClassB.GetHashCode, ClassB.GetHashCode non deve chiamare ClassA.GetHashCode in modo diretto o indiretto.

Le implementazioni del metodo GetHashCode non devono generare eccezioni.

Le classi derivate che eseguono l'override del metodo GetHashCode devono eseguire anche l'override del metodo Equals per garantire che due oggetti considerati uguali abbiano lo stesso codice hash; in caso contrario, il tipo Hashtable potrebbe non funzionare correttamente.

Esempi

In alcuni casi, il metodo GetHashCode viene implementato semplicemente per restituire un intero. Nell'esempio di codice riportato di seguito viene descritta un'implementazione del metodo GetHashCode che restituisce un intero.

Sono disponibili altre modalità più complicate per combinare i codici hash che possono migliorare le prestazioni per le tabelle hash.

Visual Basic

Imports System

Public Structure Int32
    Public value As Integer

    'other methods...
    Public Overrides Function GetHashCode() As Integer 
        Return value
    End Function 'GetHashCode
End Structure 'Int32



C#

using System;

public struct Int32 {
   public int value;

   //other methods...

   public override int GetHashCode() {
      return value;
   }
}


Visual C++

using namespace System;
public value struct Int32
{
public:
   int value;

   //other methods...
   virtual int GetHashCode() override
   {
      return value;
   }

};


Un tipo dispone spesso di più campi dati in grado di prendere parte alla creazione del codice hash. Un modo per generare un codice hash consiste nel combinare questi campi utilizzando un'operazione XOR (eXclusive OR), come indicato nell'esempio di codice che segue.

Visual Basic

Imports System

Public Structure Point
    Public x As Integer
    Public y As Integer

    'other methods
    Public Overrides Function GetHashCode() As Integer 
        Return x Xor y
    End Function 
End Structure 


C#

using System;

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

   //other methods

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


Visual C++

using namespace System;
public value struct Point
{
public:
   int x;
   int y;

   //other methods
   virtual int GetHashCode() override
   {
      return x ^ y;
   }

};


Nell'esempio di codice che segue viene descritto un altro caso in cui i campi del tipo sono combinati utilizzando l'operatore XOR (eXclusive OR) per generare il codice hash. In questo esempio di codice i campi rappresentano i tipi definiti dall'utente, ciascuno dei quali implementa GetHashCode e Equals.

Visual Basic

Imports System

Public Class SomeType
    Public Overrides Function GetHashCode() As Integer 
        Return 0
    End Function 
End Class 

Public Class AnotherType
    Public Overrides Function GetHashCode() As Integer 
        Return 1
    End Function 
End Class 

Public Class LastType
    Public Overrides Function GetHashCode() As Integer 
        Return 2
    End Function 
End Class 

Public Class Demo
    Private a As New SomeType()
    Private b As New AnotherType()
    Private c As New LastType()

    Public Overrides Function GetHashCode() As Integer 
        Return a.GetHashCode() Xor b.GetHashCode() Xor c.GetHashCode()
    End Function 
End Class 


C#

using System;

public class SomeType {
   public override int GetHashCode() {
     return 0;
   }
}

public class AnotherType {
   public override int GetHashCode() {
     return 1;
   }
}

public class LastType {
   public override int GetHashCode() {
     return 2;
   }
}

public class MyClass {
   SomeType a = new SomeType();
   AnotherType b = new AnotherType();
   LastType c = new LastType();

   public override int GetHashCode () {
     return a.GetHashCode() ^ b.GetHashCode() ^ c.GetHashCode();
   }
}


Visual C++

using namespace System;
public ref class SomeType
{
public:
   virtual int GetHashCode() override
   {
      return 0;
   }

};

public ref class AnotherType
{
public:
   virtual int GetHashCode() override
   {
      return 1;
   }

};

public ref class LastType
{
public:
   virtual int GetHashCode() override
   {
      return 2;
   }

};

public ref class MyClass
{
private:
   SomeType^ a;
   AnotherType^ b;
   LastType^ c;

public:
   virtual int GetHashCode() override
   {
      return a->GetHashCode() ^ b->GetHashCode() ^ c->GetHashCode();
   }

};


Se il membro dati della classe derivata è maggiore di Int32, è possibile combinare i bit superiori del valore con i bit inferiori utilizzando un'operazione XOR (eXclusive OR), come indicato nell'esempio di codice che segue.

Visual Basic

Imports System

Public Structure Int64
    Public value As Long

    'other methods...
    Public Overrides Function GetHashCode() As Integer 
        Return (Fix(value) Xor Fix(value >> 32))
    End Function 
End Structure 


C#

using System;

public struct Int64 {
   public long value;

   //other methods...

   public override int GetHashCode() {
      return ((int)value ^ (int)(value >> 32));
   }
}


Visual C++

using namespace System;
public value struct Int64
{
public:
   long value;

   //other methods...

   virtual int GetHashCode() override
   {
      return ((int)value ^ (int)(value >> 32));
   }
};


Informazioni sulla versione

.NET Framework

Supportato in: 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supportato in: 4, 3.5 SP1

Supportato in:
Piattaforme

Windows 7, Windows Vista SP1 o versione successiva, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (componenti di base del server non supportati), Windows Server 2008 R2 (componenti di base del server supportati con SP1 o versione successiva), Windows Server 2003 SP2

.NET Framework non supporta tutte le versioni di ciascuna piattaforma. Per un elenco delle versioni supportate, vedere Requisiti di sistema di .NET Framework.
Vedere anche

Riferimenti