C# Dictionary.FirstOrDefault()如何确定是否找到结果

C# Dictionary.FirstOrDefault()如何确定是否找到结果,c#,.net,linq,C#,.net,Linq,我有(或想有)这样的代码: IDictionary<string,int> dict = new Dictionary<string,int>(); // ... Add some stuff to the dictionary. // Try to find an entry by value (if multiple, don't care which one). var entry = dict.FirstOrDefault(e => e.Value ==

我有(或想有)这样的代码:

IDictionary<string,int> dict = new Dictionary<string,int>();
// ... Add some stuff to the dictionary.

// Try to find an entry by value (if multiple, don't care which one).
var entry = dict.FirstOrDefault(e => e.Value == 1);
if ( entry != null ) { 
   // ^^^ above gives a compile error:
   // Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>'
}
if ( entry != default(KeyValuePair<string,int>) ) 
public static bool TryFirstOrDefault<T>(this IEnumerable<T> source, out T value)
{
    value = default(T);
    using (var iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            value = iterator.Current;
            return true;
        }
        return false;
    }
}
    static void Main(string[] args)
    {
        var dict = new Dictionary<int, string>
        {
            {3, "ABC"},
            {7, "HHDHHGKD"}
        };

        bool found = false;
        var entry = dict.FirstOrDefault(d => d.Key == 3 && (found=true));
        if (found)
        {
            Console.WriteLine("found: " + entry.Value);
        }
        else
        {
            Console.WriteLine("not found");
        }
        Console.ReadLine();
    }
IDictionary dict=new Dictionary();
// ... 在字典里加些东西。
//尝试按值查找条目(如果有多个条目,则不关心哪个条目)。
var条目=dict.FirstOrDefault(e=>e.Value==1);
如果(条目!=null){
//上面的^^^给出了一个编译错误:
//运算符“!=”不能应用于“System.Collections.Generic.KeyValuePair”和“System.Collections.Generic.KeyValuePair”类型的操作数
}
我还试着像这样改变冒犯的台词:

IDictionary<string,int> dict = new Dictionary<string,int>();
// ... Add some stuff to the dictionary.

// Try to find an entry by value (if multiple, don't care which one).
var entry = dict.FirstOrDefault(e => e.Value == 1);
if ( entry != null ) { 
   // ^^^ above gives a compile error:
   // Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>'
}
if ( entry != default(KeyValuePair<string,int>) ) 
public static bool TryFirstOrDefault<T>(this IEnumerable<T> source, out T value)
{
    value = default(T);
    using (var iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            value = iterator.Current;
            return true;
        }
        return false;
    }
}
    static void Main(string[] args)
    {
        var dict = new Dictionary<int, string>
        {
            {3, "ABC"},
            {7, "HHDHHGKD"}
        };

        bool found = false;
        var entry = dict.FirstOrDefault(d => d.Key == 3 && (found=true));
        if (found)
        {
            Console.WriteLine("found: " + entry.Value);
        }
        else
        {
            Console.WriteLine("not found");
        }
        Console.ReadLine();
    }
if(条目!=默认值(KeyValuePair))
但这也会导致编译错误:

Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and 'System.Collections.Generic.KeyValuePair<string,int>'
运算符“!=”无法应用于“System.Collections.Generic.KeyValuePair”和“System.Collections.Generic.KeyValuePair”类型的操作数
这里有什么

这样做:

if ( entry.Key != null )
问题是
FirstOrDefault
方法返回一个值类型,因此它不能是
null
。您必须通过检查其
属性中是否至少有一个具有默认值来确定是否找到了值
Key
的类型为
string
,因此检查
null
是有意义的,因为字典中不能有带有
null
键的项

您可以使用的其他方法:

var entry = dict.Where(e => e.Value == 1)
                .Select(p => (int?)p.Value)
                .FirstOrDefault();

这会将结果投影到一个可为空的整数集合中,如果该集合为空(无结果),则会得到一个空值——您不可能将其误认为是成功搜索将产生的
int

Jon的答案将与
字典
一起使用,因为字典中不能有空键值。但是,它不适用于
字典
,因为它不表示空键值。。。“失败”模式将以0键结束

两种选择:

编写一个
TryFirstOrDefault
方法,如下所示:

IDictionary<string,int> dict = new Dictionary<string,int>();
// ... Add some stuff to the dictionary.

// Try to find an entry by value (if multiple, don't care which one).
var entry = dict.FirstOrDefault(e => e.Value == 1);
if ( entry != null ) { 
   // ^^^ above gives a compile error:
   // Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>'
}
if ( entry != default(KeyValuePair<string,int>) ) 
public static bool TryFirstOrDefault<T>(this IEnumerable<T> source, out T value)
{
    value = default(T);
    using (var iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            value = iterator.Current;
            return true;
        }
        return false;
    }
}
    static void Main(string[] args)
    {
        var dict = new Dictionary<int, string>
        {
            {3, "ABC"},
            {7, "HHDHHGKD"}
        };

        bool found = false;
        var entry = dict.FirstOrDefault(d => d.Key == 3 && (found=true));
        if (found)
        {
            Console.WriteLine("found: " + entry.Value);
        }
        else
        {
            Console.WriteLine("not found");
        }
        Console.ReadLine();
    }
publicstaticbooltryfirstordefault(此IEnumerable源,out T值)
{
值=默认值(T);
使用(var iterator=source.GetEnumerator())
{
if(iterator.MoveNext())
{
value=iterator.Current;
返回true;
}
返回false;
}
}
或者,投影到可为空的类型:

var entry = dict.Where(e => e.Value == 1)
                .Select(e => (KeyValuePair<string,int>?) e)
                .FirstOrDefault();

if (entry != null)
{
    // Use entry.Value, which is the KeyValuePair<string,int>
}
var entry=dict.Where(e=>e.Value==1)
.选择(e=>(KeyValuePair?)e)
.FirstOrDefault();
if(条目!=null)
{
//使用entry.Value,它是KeyValuePair
}

对于可为空的值类型,只需检查即可

if ( entry.Value != null ) { 
     //do stuff
} 
对于不可为null的类型,请检查againts默认值,对于int,为0

if ( entry.Value != 0) { 
   //do stuff
} 

无论键和值的类型如何,都可以执行以下操作:

IDictionary<string,int> dict = new Dictionary<string,int>();
// ... Add some stuff to the dictionary.

// Try to find an entry by value (if multiple, don't care which one).
var entry = dict.FirstOrDefault(e => e.Value == 1);
if ( entry != null ) { 
   // ^^^ above gives a compile error:
   // Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>'
}
if ( entry != default(KeyValuePair<string,int>) ) 
public static bool TryFirstOrDefault<T>(this IEnumerable<T> source, out T value)
{
    value = default(T);
    using (var iterator = source.GetEnumerator())
    {
        if (iterator.MoveNext())
        {
            value = iterator.Current;
            return true;
        }
        return false;
    }
}
    static void Main(string[] args)
    {
        var dict = new Dictionary<int, string>
        {
            {3, "ABC"},
            {7, "HHDHHGKD"}
        };

        bool found = false;
        var entry = dict.FirstOrDefault(d => d.Key == 3 && (found=true));
        if (found)
        {
            Console.WriteLine("found: " + entry.Value);
        }
        else
        {
            Console.WriteLine("not found");
        }
        Console.ReadLine();
    }
static void Main(字符串[]args)
{
var dict=新字典
{
{3,“ABC”},
{7,“hhdhgkd”}
};
bool-found=false;
var条目=dict.FirstOrDefault(d=>d.Key==3&&(found=true));
如果(找到)
{
Console.WriteLine(“找到:+entry.Value”);
}
其他的
{
控制台。写入线(“未找到”);
}
Console.ReadLine();
}

公平地说,不需要强制转换对象或使用select语句,我也不会依靠try-catch来解决问题

既然你用的是Linq,那么用它有什么问题吗

var entry;
if (dict.Any(e => e.Value == 1))
{
    // Entry was found, continue work...
    entry = dict.FirstOrDefault(e => e.Value == 1);
}
else
{
    // Entry was not found.
    entry = -1;
}
显然,可以使用它来适应您的解决方案,但是如果它在集合中找到具有该值的项,则会很快停止检查。因此,如果找到匹配项,它不会检查所有值

MSDN文档:

公共静态TValue FirstOrDefault(此字典,Func-where)
{
foreach(字典中的var kv)
{
如果(其中(千伏))
返回千伏值;
}
返回默认值;
}

我认为最清晰的代码是:

if (dict.ContainsValue(value))
  string key = dict.First(item => item.Value == value).Key;
else
  // do somehing else

虽然从速度的角度来看这并不好,但没有更好的解决方案。这意味着第二次将使用慢速搜索来搜索词典。应该通过提供“bool TryGetKey(value)”方法来改进Dictionary类。这看起来有点奇怪——因为字典被认为是在另一个方向使用的——但有时向后翻译是不可避免的。

。。。第一个选项不适用于不可为null的类型key@KingOfHypocrites只需检查该类型的默认值。。。例如
0
而不是
null
如果值泛型类型是不可空的,会发生什么?很好,在这种情况下,我们需要比较该类型的默认值。对于字典(entry.Value!=0)。在我的例子中,值类型是可以为null的。您也可以简单地“双重检查”结果,条件与您所查找的完全相同:dict.FirstOrDefault(e=>e.value==1)。value.value==1@YoupTube:这是一个太多的
Value
调用,如果您要查找的值为0,它将不会做正确的事情。有人能解释一下如何使用
TryFirstOrDefault()
?我应该把lambda表达式放在哪里,什么是
?这是唯一的示例代码吗?@testing:没有lambda表达式可放入-
value
是一个输出参数,它接收序列中第一个元素的值(如果有),或者默认值
T
,否则,就像(假设)
int.TryParse
。如果需要,您可以创建一个接受谓词的重载,但不必这样做-您可以根据示例代码,首先使用
Where
调用。