I have declared and populated the following collection.
protected static Dictionary<string, string> _tags;
Now I want to look locate a particular entry in the collection. I tried the following.
thisTag = _tags.FirstOrDefault(t => t.Key == tag);
if (thisTag != default(KeyValuePair<string, string>))
...
And I get the error:
Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair' and ''
Initially I attempted to compare the result to null
, and I guess that's not supported with struct
s.
I would've thought that finding an item within a collection is a very trivial task. So how the heck to I determine if the item I'm looking for was found?
(Note: I'm using Dictionary
because I want fast lookups. I know I can use Contains()
to determine if the item is there. But that means a total of two lookups, which sort of defeats the purpose of having a fast lookup. I'll happily using a different collection if it can quickly lookup an item and I have a way to determine if it was successful.)
thisTag = _tags.FirstOrDefault(t => t.Key == tag);
is an inefficient and a little bit strange way to find something by key in a dictionary. Looking things up for a Key is the basic function of a Dictionary.
The basic solution would be:
if (_tags.Containskey(tag)) { string myValue = _tags[tag]; ... }
But that requires 2 lookups.
TryGetValue(key, out value)
is more concise and efficient, it only does 1 lookup. And that answers the last part of your question, the best way to do a lookup is:
string myValue;
if (_tags.TryGetValue(tag, out myValue)) { /* use myValue */ }
VS 2017 update, for C# 7 and beyond we can declare the result variable inline:
if (_tags.TryGetValue(tag, out string myValue))
{
// use myValue;
}
// use myValue, still in scope, null if not found
Sometimes you still need to use FirstOrDefault if you have to do different tests.
If the Key component of your dictionnary is nullable, you can do this:
thisTag = _tags.FirstOrDefault(t => t.Key.SubString(1,1) == 'a');
if(thisTag.Key != null) { ... }
Using FirstOrDefault, the returned KeyValuePair's key and value will both be null if no match is found.
Of course, if you want to make sure it's in there otherwise fail then this works:
thisTag = _tags[key];
NOTE: This will fail if the key,value pair does not exists but sometimes that is exactly what you want.
This way you can catch it and do something about the error.
I would only do this if I am certain that the key,value pair is or should be in the dictionary and if not I want it to know about it via the throw.
It's possible to find the element in Dictionary collection by using ContainsKey or TryGetValue as follows:
class Program
{
protected static Dictionary<string, string> _tags = new Dictionary<string,string>();
static void Main(string[] args)
{
string strValue;
_tags.Add("101", "C#");
_tags.Add("102", "ASP.NET");
if (_tags.ContainsKey("101"))
{
strValue = _tags["101"];
Console.WriteLine(strValue);
}
if (_tags.TryGetValue("101", out strValue))
{
Console.WriteLine(strValue);
}
}
}