Sring e metodo GetHashCode()

martedì 06 marzo 2012 - 16.40
Tag Elenco Tags  C#  |  .NET 3.5

andrestu Profilo | Expert

se ho due stringhe:

s1 = "ABCDEFG";
s2 = "ABCDEFG";

il numero restituito dal metodo GetHashCode sia su s1 che su s2 sarà sempre identico?
in base a un breve test effettuato sembrerebbe di si, volevo solo avere la conferma al 100% oppure ci può essere qualche eventualità a me sconosciuta che fà in modo che mi restituisca numeri diversi?

grazie

Andrea Restucci - Web Developer

alx_81 Profilo | Guru

>il numero restituito dal metodo GetHashCode sia su s1 che su s2 sarà sempre identico?
>in base a un breve test effettuato sembrerebbe di si, volevo
>solo avere la conferma al 100% oppure ci può essere qualche eventualità
>a me sconosciuta che fà in modo che mi restituisca numeri diversi?
sì, ma vale solo per i tipi non strutturati. se lo fai su due oggetti che hanno proprietà identiche (ma sono due oggetti) avrai valori diversi.


369x592 16Kb


intanto che ci sono ti consiglio, qualora non lo conosca già, di usare linqpad per questi esempi: http://www.linqpad.net/

>grazie
di nulla!
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

andrestu Profilo | Expert

ok grazie, si in effetti avevo letto qualcosa sull'msdn ma per il momento il metodo mi serve semplicemente per memorizzare delle chiavi tipo stringa, quindi lo chiamo esclusivamente sui tipi stringa.
Lo utilizzo perchè può capitare che le stringhe (chiavi) che utilizzo sono molto lunghe e ho visto che in questo modo si riducono notevolmente...

Andrea Restucci - Web Developer

InsettoScoppiettato Profilo | Junior Member

un filo di teoria per chiarire la questione: il metodo GetHashCode() serve per generare dei riferimenti interi per classi non standard.
Lo scopo di tale procedura è unicamente uno: permettere alla classe che uno sta creando, qualora servisse, di poter gestire una chiamata al metodo Equals() in maniera efficiente.
Questo viene particolarmente utile quando la classe viene usata come chiave di una mappa (Dizionario, tabella di Hash o grafo che sia), in quando all'inserimento di un nuovo KeyValuePair all'interno della struttura dati, il compilatore chiama Equals su ogni elemento per capire dove inseire la struttura richiesta. Se la classe è un'intero o una stringa la cosa è semplice,il metodo GetHashCode() richiama direttamente il numero o la reppresentazione intera di tale numero, ma se la struttura è Custom allora ci deve pensare il programmtore a generare qualcosa si sensato.
L'obiettivo finale è sempre lo tesso: pensare a tutti i posssibili valori che la classe potrà contenere (campo per campo), identificare un range e spalmare uniformemente questo range immaginario sul campo intero (o meglio sul campo Int32), in modo che nell'uso generico standard, i numeri di hash che vengono generati siano molto diversi tra di loro e uniformemente densi in Int32.
Questo permette una maggior efficienza durante i processi di ordinamento e ricerca su strutture dati complesse (non le liste o le SortedLists o gli array, che sono invece ordinati per posizione) e accoppiate (chiave/Valore).

NOTA: Il metodo Equals() chiama sempre GetHashCode().
NOTA 2: il CLR restituisce sempre warning se una classe sovraccarica l'interfaccia IComparable o sovraccarica gli operatori == e !=. Vuole un GetHashCode() sensato per quella classe, non perchè serva, ma perchè tale classe può essere una chiave per una struttura ordinata e GetHashCode() a tal punto viene chiamato ad ogni interazione con la struttura stessa.

In ultimo, GetHasCode per le strutture valore deriva sempre dai tipo valore che contiene. Per i tipi riferimento (le classi in generale, tale metodo è basato sulla chiamata di object.GetHashCode(), il che non fa altro che scalare sul campo Int32 l'indirizzo fisico nell'heap; questo porta a dire che due classi uguali non avranno mai lo stesso valore di hash visto il fatto che non risiedono mai sulla stessa posizione di memoria, pur contenendo tutte e due gli stessi valori (campo per campo). Per assurdo, una classe
class A{ public class1 field1; public class2 field2; public class3 field3; public A() { field1= new class1(); field2 = new class2(); field3 = new class3(); } } e due istanze definite come A istanza1 = new A(); A istanza2 = new A(); istanza2.field1 = istanza1.field1; istanza2.field2 = istanza1.field2; istanza2.field3 = istanza1.field3;

Risulterà sempre che istanza1.GetHashCode() risulta diverso da istanza2.GetHashCode() (il che è concettualmente sbagliato anche per scopi comuni senza dizionari o mappe).


Alessandro Parma
Programmazione multipla scoposta con prognosi ancora da definirsi

alx_81 Profilo | Guru

>un filo di teoria per chiarire la questione:
grazie
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

alexmed Profilo | Guru

Ciao
mi riaggancio a questo Post anche se la mia domanda riguarda l'opposto.
Volevo sapere se due date diverse restituiscono due codici diversi o meglio se due date diverse possono restituire valori uguali.
Mi serve per generare un codice univoco per degli utenti.

Grazie
alexmed

alx_81 Profilo | Guru

>Ciao
>mi riaggancio a questo Post anche se la mia domanda riguarda l'opposto.
>Volevo sapere se due date diverse restituiscono due codici diversi
>o meglio se due date diverse possono restituire valori uguali.
>Mi serve per generare un codice univoco per degli utenti.
diciamo che un codice così:

DateTime d1 = new DateTime(2012,12,10,10,0,0); DateTime d2 = new DateTime(2012,12,10,5,0,0); d1.GetHashCode(); d2.GetHashCode();

torna due valori differenti, ma perchè invece non usi il tick?
http://msdn.microsoft.com/library/system.datetime.ticks.aspx

>Grazie
di nulla!
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.microsoft.com/profiles/Alessandro.Alpi
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5