3

I have a simple dictionary like this:

Dictionary<string[], object[]> list = new Dictionary<string[], object[]>();

I add items with:

list.Add(new string[] {"a", "a", "a"}, new object[]{ });

The problem appear when i try to get value by key

object[] values;   
if(list.TryGetValue(new string[] {"a", "a", "a"}, out values)
{  }

always return null. Seems that he cannot find this key in dictionary but as you can see there is...

Thanks for help

jorgonor
  • 1,679
  • 10
  • 16
Mirko Fogazzi
  • 163
  • 3
  • 17
  • I think you need a custom comparer that uses SequenceEquals – Poody Nov 04 '16 at 12:21
  • When I see 'simple dictionary' like this, first thought is always that something is wrong with the design here. Are you sure this is necessary? Maybe we could help with redesign? The reference difference has already been explained both in comments and in answer below, so I won't even bother. – Jakub Szumiato Nov 04 '16 at 12:24
  • I have simplified the structure to explane and solve my problem. I'm writing an application that make purchase forcast based on movements of items in warehouse and offer a tool to join more data comes from different source in one with help of same columns named "key" – Mirko Fogazzi Nov 04 '16 at 18:38

3 Answers3

6

As already answered, each array is indeed different object. By default, arrays are compared using object reference, without taking into account the actual content of the array. You can work around this by implementing your own array comparer, like this:

class ArrayComparer<T> : IEqualityComparer<T[]> {
    public bool Equals(T[] x, T[] y) {
        return ((IStructuralEquatable) x).Equals((IStructuralEquatable) y, EqualityComparer<T>.Default);
    }

    public int GetHashCode(T[] obj) {
        return ((IStructuralEquatable) obj).GetHashCode(EqualityComparer<T>.Default);
    }
}

It works using built-in Array functionality (Array implements IStructuralEquatable) to provide equality and hashcode operations which respect array elements. Then you do:

Dictionary<string[], object[]> list = new Dictionary<string[], object[]>(new ArrayComparer<string>());

And it will work even if you pass different instances or arrays. Whether you should have a dictionary where keys are arrays is a different story....

Evk
  • 98,527
  • 8
  • 141
  • 191
1

Each array you create is a different object, and therefore only the same array you used as the key can be used to find it. Another array with the same values won't be the same array.

If the number of values is fixed you can use a Tuple<string, string, string> as the key.

If it is variable you can define a custom IEqualityComparer. Check out this question for how to do it.

Community
  • 1
  • 1
AlexDev
  • 4,049
  • 31
  • 36
0

Get the reference: var key = new string[] {"a", "a", "a"};

 Dictionary<string[], object[]> list = new Dictionary<string[], object[]>();
 var key = new string[] { "a", "a", "a" };
 list.Add(key, new object[] { });
 object[] values;   

 if(list.TryGetValue(key, out values))
 {

 }
Bose_geek
  • 498
  • 5
  • 18
  • The problem here is that if you are reading the array values in from a DB or file you'll end up creating a new object and cannot use an existing "equal" reference. – juharr Nov 04 '16 at 12:37