Cannot Find Key in Generic Dictionary [duplicate]
I cannot find a dictionary entry by key. I have an interface like the following:
public interface IFieldLookup
{
string FileName { get; set; }
string FieldName { g开发者_JS百科et; set; }
}
Then I have a dictionary like so:
Dictionary<IFieldLookup, IField> fd
When I try to retrieve an element out of the dictionary by the key, I get a KeyNotFoundException. I am assuming that I have to implement some type of comparison - if my assumption is correct, what is the recommended way of implementing a comparison in this case?
use ContainsKey and override equals on the key class
Ok lets say this is our key class:
class Key
{
public int KeyValue;
public override bool Equals(object o)
{
return (((Key)o).KeyValue == KeyValue);
}
}
now lets use the class as a key
Dictonary<Key, string> dict = new Dictonary<Key, string>();
Key k = new Key();
k.KeyValue = 123;
dict.Add(k, "Save me!");
Key k2 = new Key();
k2.KeyValue = 123;
if (dict.ContainsKey(k2))
{
string value = dict[k2];
}
Since this is an interface rather than a class, you will have to define your equality operator for every class that implements the interface. And those operators will need to operate consistantly. (This would be much better if it were a class rather than an interface.)
You must override the Equals(object)
and GetHashCode()
methods on each class.
Probably something like this:
public override bool Equals(object obj)
{
IFieldLookup other = obj as IFieldLookup;
if (other == null)
return false;
return other.FileName.Equals(this.FileName) && other.FieldName.Equals(this.FieldName);
}
public override int GetHashCode()
{
return FileName.GetHashCode() + FieldName.GetHashCode();
}
or this:
public override bool Equals(object obj)
{
IFieldLookup other = obj as IFieldLookup;
if (other == null)
return false;
return other.FileName.Equals(this.FileName, StringComparison.InvariantCultureIgnoreCase) && other.FieldName.Equals(this.FieldName, StringComparison.InvariantCultureIgnoreCase);
}
public override int GetHashCode()
{
return StringComparer.InvariantCulture.GetHashCode(FileName) +
StringComparer.InvariantCulture.GetHashCode(FieldName);
}
Depending on how you want it to behave.
Implement an instance of IEqualityComparer<T>
(recommended by deriving from EqualityComparer<T>
for its automatic implementation of IEqualityComparer
as well) for the key type, and pass an instance to the dictionary constructor. This way you can implement the comparison consistently across multiple implementations of the interface.
精彩评论