I need to use a byte[]
as a key in a Dictionary
. Since byte[]
doesn't override the default GetHashCode
method, two separate byte[]
objects that contain the same data will use two separate slots in the dictionary. Basically what I want is this:
Dictionary<byte[], string> dict = new Dictionary<byte[], string>(); dict[new byte[] {1,2,3}] = "my string"; string str = dict[new byte[] {1,2,3}]; // I'd like str to be set to "my string" at this point
Is there a simple way to do this? The only thing I can think of would be to build a wrapper class that just contains a byte[]
and override GetHashCode
based on the contents of the byte[]
, but this seems error prone.
By default byte[]
will be compared by reference which is not what you want in this case. What you need to do is specify a custom IEqualityComparer<byte[]>
and do the comparison you want.
For example
public class ByteArrayComparer : IEqualityComparer<byte[]> { public bool Equals(byte[] left, byte[] right) { if ( left == null || right == null ) { return left == right; } return left.SequenceEqual(right); } public int GetHashCode(byte[] key) { if (key == null) throw new ArgumentNullException("key"); return key.Sum(b => b); } }
Then you can do
var dict = new Dictionary<byte[], string>(new ByteArrayComparer());
Solution for 2.0
public class ByteArrayComparer : IEqualityComparer<byte[]> { public bool Equals(byte[] left, byte[] right) { if ( left == null || right == null ) { return left == right; } if ( left.Length != right.Length ) { return false; } for ( int i= 0; i < left.Length; i++) { if ( left[i] != right[i] ) { return false; } } return true; } public int GetHashCode(byte[] key) { if (key == null) throw new ArgumentNullException("key"); int sum = 0; foreach ( byte cur in key ) { sum += cur; } return sum; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With