简体   繁体   中英

C# containskey on tuple

I have a dictionary that takes in a tuple function and an int

Dictionary<Tuple<string,string>, int> fullNames = new Dictionary<Tuple<string,string>, int>();

Where the Tuple class is defined as

public class Tuple<T, T2> 
{ 
    public Tuple(T first, T2 second) 
    { 
        First = first; 
        Second = second; 
    } 
    public T First { get; set; } 
    public T2 Second { get; set; } 

}

I want to use the Containskey function as such

if (fullNames.ContainsKey(Tuple<"firstname","lastname">))

But I am getting an overload error. Any suggestions?

The code you have provided is invalid, since you're trying to provide a type definition in the place where an actual object should be (and the type definition is invalid too, since a string is not actually the type System.String that a generic expects). If the tuple is the key value for the dictionary, then you can do this:

if(fullNames.ContainsKey(new Tuple<string, string>("firstname", "lastname")))

But then you can run afoul of the reference equality issue since two tuples created in memory with the same properties are not necesarily the same object. It would be better to do this:

Tuple<string, string> testTuple = new Tuple<string, string>("firstname", "lastname");
if(fullNames.Keys.Any(x => x.First == testTuple.First && x.Second == testTuple.Second))

That will tell you if a key exists that shares the same property data. Then accessing that element is going to be just as complicated.

EDIT: Long story short, if you plan on using a reference type for your key, you need to make sure your object implements Equals and GetHashCode in a way to properly identify two separate in memory instances are the same.

if (fullNames.ContainsKey(new Tuple<string, string> ("firstname", "lastname")))
{ /* do stuff */ }

In order to use your Tuple as key in a Dictionary<> you need to correctly implement the methods GetHashCode and Equals :

public class Tuple<T, T2> 
{ 
    public Tuple(T first, T2 second) 
    { 
        First = first; 
        Second = second; 
    } 
    public T First { get; set; } 
    public T2 Second { get; set; }

    public override int GetHashCode()
    {
      return First.GetHashCode() ^ Second.GetHashCode();
    }

    public override Equals(object other)
    {
       Tuple<T, T2> t = other as Tuple<T, T2>;
       return t != null && t.First.Equals(First) && t.Second.Equals(Second);
    }

}

Otherwise a key equality check is done by reference. With the effect that new Tuple("A", "B") != new Tuple("A", "B") .

For more information about hash code generation: What is the best algorithm for an overridden System.Object.GetHashCode?

.Net 4.0 has a Tuple type, which would work for your case since the Equal method is overloaded to use the Equal from your types.

Dictionary<Tuple<string, string>, int> fullNames = 
    new Dictionary<Tuple<string, string>, int>();
fullNames.Add(new Tuple<string, string>("firstname", "lastname"), 1);
Console.WriteLine(fullNames.ContainsKey(
    new Tuple<string, string>("firstname","lastname"))); //True
Tuple<type,type> tuple = new Tuple("firsdtname", "lastname")

您已经编写了代码来创建未知类型的atuple的实例。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM