views:

77

answers:

3

Hi

I need to arrange sort of dictionary where the key would be a pair of enum and int and value is object. So I want to map a pair to some object.

One option would be

public enum SomeEnum
{
 value1, value2
}

class Key
{
  public SomeEnum;
  public int counter;  

  // Do I have to implement Compare here?
}

Dictionary<SomeEnum, object> _myDictionary;

Another option would convert enum and int to some unique key.

string key = String.Format("{0}/{1}", enumValue, intValue)

That approach requires string parsing, a lot of extra work.

How to make it easily?

+7  A: 

I would go with something similar to

public enum SomeEnum
{
 value1, value2
}

public struct Key
{
  public SomeEnum;
  public int counter;  
}

Dictionary<Key, object>

I think that would make it?

Onkelborg
Yes, that is by far the simplest :)
leppie
How two keys would be compared by Dictionary? Does it use == or IComparable?
Captain Comic
It's a value type, so it will just perform a ==. I'm not sure about 32 bit systems, but on a 64 bit system I think it would just compare two memory locations since the enum and the int will fit into 64 bit, it's a cheap operation. On 32 bit it would probably (?) require a few more instructions?
Onkelborg
O I see just change class to struct and no worries.. Agree..
Captain Comic
+1 for simplest solution
saurabh
The advantage of this solution is performance, and simplicity. It's cheap to compare. But you can't control sorting, for example
Onkelborg
Hm, when I think about it, you can specify the order in which the fields are stored internally. That should allow you to specfiy internal relevance between the enum and the int
Onkelborg
+3  A: 

If you are using C# 4.0, you could use the Tuple class.

var key = Tuple.Create(SomeEnum.Value1, 3);
Winston Smith
Yes, but then it's not nicely typed - ie, there's not description of what the key consists of. But yes, it's possible
Onkelborg
It is strongly typed - the key is of type `Tuple<SomeEnum, int>`.
Winston Smith
So your dictionary could be defined as `Dictionary<Tuple<SomeEnum, int>, object>`
Winston Smith
Yes, it's strongly typed, but it's not descriptive. If you later get a hold of that key, do you know what that integer really is? That's my point. It may, or may not, be a problem. It depends :)
Onkelborg
It's "strongly typed" but not "nicely typed". With a struct (or an anonymous type) you can access the members by x.NameYouSpecify. With a Tuple you access x.Item1, which is nowhere near as informative.
Iain Galloway
+6  A: 

If you are going to put this in a dictionary, then you will need to make sure you implement a meaningful .Equals and .GetHashCode or the dictionary will not behave correctly.

I'd start off with something like the following for the basic compound key, and then implement a custom IComparer to get the sort order you need.

public class MyKey
{
    private readonly SomeEnum enumeration;
    private readonly int number;

    public MyKey(SomeEnum enumeration, int number)
    {
        this.enumeration = enumeration;
        this.number = number;
    }

    public int Number
    {
        get { return number; }
    }

    public SomeEnum Enumeration
    {
        get { return enumeration; }
    }

    public override int GetHashCode()
    {
        int hash = 23 * 37 + this.enumeration.GetHashCode();
        hash = hash * 37 + this.number.GetHashCode();

        return hash;
    }

    public override bool Equals(object obj)
    {
        var supplied = obj as MyKey;
        if (supplied == null)
        {
            return false;
        }

        if (supplied.enumeration != this.enumeration)
        {
            return false;
        }

        if (supplied.number != this.number)
        {
            return false;
        }

        return true;
    }
}
Rob Levine
Oh.. so much typing...(((
Captain Comic
+1 for mentioning the .Equals and GetHashCode gotcha. This is a good reason to use the Tuple type instead of rolling your own simple key.
Winston Smith
@Winston Smith - good point about Tuples
Rob Levine