The instance method GetHashCode() returns an int hash computed from a string’s characters. Collections like Dictionary<string, T> and HashSet<string> use it internally for fast lookups. It overrides Object.GetHashCode() with a string-specific algorithm.
01
Instance Method
text.GetHashCode()
02
int Return
32-bit hash code.
03
Overrides Object
From System.Object.
04
Dictionary Keys
Fast lookup.
05
Collisions
Not unique.
06
Equals Rule
Equal → same hash.
Fundamentals
Definition and Usage
In C#, every object inherits GetHashCode() from System.Object. The string type overrides it to produce a hash based on character content. Call it on any string: label.GetHashCode().
A hash code is a compact numeric fingerprint—not a copy of the string and not guaranteed unique. Hash tables use it to narrow down where to search, then call Equals() to confirm a true match. That is why equal strings must share the same hash code.
💡
Beginner Tip
You rarely call GetHashCode() directly in application code—Dictionary and HashSet call it for you when you use strings as keys. Learn it to understand collections, debugging, and the Equals/GetHashCode contract.
Foundation
📝 Syntax
Common overloads on System.String:
C#
public override int GetHashCode();
public int GetHashCode(StringComparison comparisonType);
Parameters
Default overload — no parameters; uses ordinal rules for the hash.
comparisonType — controls whether case/culture affects the hash (e.g. OrdinalIgnoreCase for case-insensitive keys).
Return Value
A 32-bit signed int hash code. The exact number may vary between .NET versions, but the same string content produces the same hash within a given runtime.
a.GetHashCode() == b.GetHashCode() (not proof of equality)
Dictionary with string key
dict[key] — uses GetHashCode internally
Confirm equality
string.Equals(a, b) — always use with hash checks
Basic hash
text.GetHashCode()
Default
Ignore case
GetHashCode(OrdinalIgnoreCase)
Overload
Dictionary
Dictionary<string,T>
Uses hash
Equals rule
Equal → same hash
Contract
Hands-On
Examples Gallery
Run with dotnet run. Each example shows how GetHashCode() behaves—from basic usage to consistency, dictionaries, case rules, and the Equals contract.
📚 Getting Started
Obtain a hash code from a string.
Example 1 — Basic GetHashCode() Usage
Get the hash code for a sample string and call it again to show consistency.
C#
using System;
class Program {
static void Main() {
string sampleString = "Hello, C#!";
int hash1 = sampleString.GetHashCode();
int hash2 = sampleString.GetHashCode();
Console.WriteLine($"Hash code: {hash1}");
Console.WriteLine($"Second call same: {hash1 == hash2}");
}
}
📤 Output:
Hash code: -1034815400
Second call same: True
How It Works
The method scans the string’s characters and returns an int fingerprint. Calling it twice on the same string returns the same value. The exact integer can differ between .NET versions, but it is stable for identical content within one runtime.
Example 2 — Equal Strings Share the Same Hash
Two different variables with the same text should produce matching hash codes.
C#
using System;
class Program {
static void Main() {
string a = "C#";
string b = "C#";
string c = "c#";
Console.WriteLine($"a.Equals(b): {a.Equals(b)}");
Console.WriteLine($"a.GetHashCode() == b: {a.GetHashCode() == b.GetHashCode()}");
Console.WriteLine($"a.Equals(c): {a.Equals(c)}");
Console.WriteLine($"a.GetHashCode() == c: {a.GetHashCode() == c.GetHashCode()}");
}
}
When Equals is true, hash codes match. When content differs (case-sensitive default), hashes typically differ too—though unequal strings can occasionally collide (rare with normal data).
📈 Practical Patterns
Collections, case rules, and the Equals/GetHashCode contract.
Example 3 — Dictionary Uses GetHashCode() Internally
String keys in a Dictionary rely on hash codes for fast retrieval.
C#
using System;
using System.Collections.Generic;
class Program {
static void Main() {
Dictionary<string, int> scores = new Dictionary<string, int> {
{ "Alice", 95 },
{ "Bob", 88 }
};
string key = "Alice";
Console.WriteLine($"Lookup key: {key}");
Console.WriteLine($"Score: {scores[key]}");
Console.WriteLine($"(Dictionary hashed \"{key}\" internally to find this value)");
}
}
📤 Output:
Lookup key: Alice
Score: 95
(Dictionary hashed "Alice" internally to find this value)
How It Works
When you access scores["Alice"], the dictionary hashes "Alice" to find the right bucket, then confirms with Equals. You do not call GetHashCode() yourself—the collection handles it.
Example 4 — Case-Insensitive Hash Overload
Use StringComparison.OrdinalIgnoreCase when case should not affect the hash.
C#
using System;
class Program {
static void Main() {
string upper = "Admin";
string lower = "admin";
int defaultA = upper.GetHashCode();
int defaultB = lower.GetHashCode();
int ignoreA = upper.GetHashCode(StringComparison.OrdinalIgnoreCase);
int ignoreB = lower.GetHashCode(StringComparison.OrdinalIgnoreCase);
Console.WriteLine($"Default hashes equal: {defaultA == defaultB}");
Console.WriteLine($"IgnoreCase hashes equal: {ignoreA == ignoreB}");
}
}
The default hash is case-sensitive. The overload with OrdinalIgnoreCase treats "Admin" and "admin" as the same for hashing—useful when building custom case-insensitive lookup structures.
Example 5 — The Equals / GetHashCode Contract
If two strings are equal, their hash codes must match—required for collections to work correctly.
Separate objects, same text:
Equals: True
Hashes match: True
ReferenceEquals: False
How It Works
s1 and s2 are different objects in memory but equal in content. Hash codes match because hashing uses content, not reference identity. Dictionary depends on this rule.
Applications
🚀 Common Use Cases
Dictionary and HashSet keys — fast string lookup in collections.
Deduplication — HashSet<string> uses hash codes to track unique values.
Custom comparers — pairing hash with equality in user-defined types that contain strings.
Debugging collections — inspect why keys might not be found (hash/equality mismatch).
Case-insensitive maps — hash with OrdinalIgnoreCase for custom structures.
🧠 How GetHashCode() Works
1
String content is read
The runtime processes characters (ordinal or comparison rules).
Input
2
Hash algorithm runs
Characters combine into a 32-bit int fingerprint.
Compute
3
Collections use the hash
Dictionary/HashSet pick a bucket, then verify with Equals.
Use
=
🔗
int returned
Compact numeric fingerprint—not unique, not cryptographic.
Important
📝 Notes
Hash codes are not guaranteed unique—collisions can occur.
Never use hash codes alone for security (passwords, tokens)—they are not encryption.
Equal strings must return equal hash codes (Equals/GetHashCode contract).
Changing string content changes the hash—strings are immutable, so the hash is stable for a given instance.
Exact hash values may differ across .NET versions; do not persist hashes long-term unless documented.
Use the StringComparison overload when case rules should affect hashing.
Performance
⚡ Optimization
GetHashCode() is optimized for collection use. Avoid calling it repeatedly in tight loops when the string has not changed—cache the result if needed. Let Dictionary and HashSet manage hashing for you rather than building manual hash maps. For cryptographic needs, use SHA256 or similar—not GetHashCode().
Wrap Up
Conclusion
The C# GetHashCode() method turns string content into a numeric fingerprint for hash-based collections. Understand collisions, the Equals/GetHashCode contract, and the case-sensitive overload to use strings effectively as dictionary keys.
Practice the examples above, then continue to GetType() to learn how to inspect runtime type information.
Let Dictionary/HashSet call GetHashCode for string keys
Keep Equals and GetHashCode consistent in custom types
Use StringComparison overload for case-insensitive hashing
Use Equals() to confirm equality after hash match
Use cryptographic hashes for security-sensitive data
❌ Don’t
Assume hash codes are unique identifiers
Compare strings using only GetHashCode()
Use GetHashCode for password or token security
Store hash codes expecting them never to change across .NET versions
Break the rule: equal objects must have equal hash codes
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about GetHashCode()
Use these points whenever you work with string hashing in C#.
5
Core concepts
🔗01
int Hash
32-bit fingerprint.
Basics
🗃02
Dictionary
Key lookup.
Use case
⚠️03
Collisions
Not unique.
Caution
📑04
Equals Rule
Equal → same hash.
Contract
🔄05
Comparison
Case overload.
Overload
❓ Frequently Asked Questions
GetHashCode() returns a 32-bit integer hash computed from the string's character content. It overrides Object.GetHashCode(). Hash codes help collections like Dictionary and HashSet locate keys quickly. Call it as text.GetHashCode().
int hash = text.GetHashCode(); Overload: text.GetHashCode(StringComparison.OrdinalIgnoreCase) when case rules should affect the hash. No parameters on the default overload.
It returns int—a hash code derived from the string contents. Equal strings (under the same comparison rules) must produce the same hash. Different strings may produce the same hash (collision), though good algorithms minimize that.
No. Hash codes are not unique identifiers. Two different strings can share the same hash (collision). Never assume hash alone proves equality—always use Equals() to confirm.
They use hash codes to bucket keys for fast lookup. When you add a string key, the collection calls GetHashCode() to decide where to store it, then uses Equals() to resolve any collisions in that bucket.
If two strings are equal according to Equals(), they must return the same GetHashCode(). The reverse is not required—unequal strings may share a hash. Breaking this rule breaks Dictionary and HashSet behavior.
Did you know?
Starting with .NET Core, string hash codes use a randomized algorithm per process for some scenarios to mitigate hash-flooding attacks in collections. That is another reason not to rely on specific hash integer values across app restarts or .NET versions—only on the Equals/GetHashCode contract within one running application.