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

3
  • I think you need a custom comparer that uses SequenceEquals Commented Nov 4, 2016 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. Commented Nov 4, 2016 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" Commented Nov 4, 2016 at 18:38

3 Answers 3

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....

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks it works great but if i try to find a key that has in array a string with character '/' it return null.
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.

2 Comments

No strings in keys array are not fixed it changes based on the user input
Or you could implement your own equality comparer.
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))
 {

 }

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.