ChatGPT解决这个技术问题 Extra ChatGPT

如何确保 FirstOrDefault<KeyValuePair> 已返回值

这是我正在尝试做的简化版本:

var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");

var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

由于字典中不存在“xyz”,因此 FirstOrDefault 方法将不会返回有效值。我希望能够检查这种情况,但我意识到我无法将结果与“null”进行比较,因为 KeyValuePair 是一个结构。以下代码无效:

if (day == null) {
    System.Diagnotics.Debug.Write("Couldn't find day of week");
}

我们您尝试编译代码,Visual Studio 会抛出以下错误:

Operator '==' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<int,string>' and '<null>'

如何检查 FirstOrDefault 是否返回了有效值?

你有一个错误,但我认为这是一个复制粘贴的事情:days 不是一个列表,你不能在 KeyValuePair 上使用 add。
哎呀...你是对的,我是从记忆中输入的,我显然犯了一个错误。感谢您指出。
可能是: var days = new Dictionary();

T
Tod

FirstOrDefault 不返回 null,它返回 default(T)
您应该检查:

var defaultDay = default(KeyValuePair<int, string>);
bool b = day.Equals(defaultDay);

MSDN - Enumerable.FirstOrDefault<TSource>

如果源为空,则默认(TSource);否则,源中的第一个元素。

笔记:

如果您的代码是通用的,最好使用 EqualityComparer.Default.Equals(day, defaultDay),因为 .Equals 可能会被覆盖或 day 可能为空。

在 C# 7.1 中,您将能够使用 KeyValuePair defaultDay = default;,请参阅目标类型的“默认”文字。

另请参阅:参考源 - FirstOrDefault


+1,KeyValuePair是值类型(struct),不是引用类型(class),也不是可以为null的值类型,所以不能为null。
@paper1337 - 谢谢,但我在哪里错过了 typeof?此代码编译并工作。
我来到这里是因为我不清楚 default(KeyValuePair<T1, T2>) 会导致什么。好吧,应该很明显,它会导致一个空的 KVP。但是由于“显而易见”并不是编写正确应用程序的好方法(而且我当前的实现太复杂而无法清楚/干净地引发这种情况),我用一个新项目尝试了它 - 实际上 - 它返回了一个 KeyValuePair属性 KeyValue 都是 NULL .... 只是为了在这 5 分钟的愚蠢中保护其他人 ;-)
@Nicolas - 这里没有愚蠢。检查自己并确保您理解您的代码始终是一个好主意。我添加了一个指向 default 关键字的链接,这里显然缺少它。谢谢!
@JeffBridgman - 这真的是一个好点!具体来说,这是不可能的,因为我们正在使用 KeyValuePair。如果您有通用代码,day.Equals 甚至不是 null 安全的,我会使用 EqualityComparer<T>.Default.Equals(day, defaultDay)
p
peaceoutside

这是我认为最清晰简洁的方式:

var matchedDays = days.Where(x => sampleText.Contains(x.Value));
if (!matchedDays.Any())
{
    // Nothing matched
}
else
{
    // Get the first match
    var day = matchedDays.First();
}

这完全解决了对结构使用奇怪的默认值的东西。


问题在于,有可能(取决于实现)可枚举的天数将被枚举两次,或者更糟糕的是,在 Any() 和 First() 调用之间返回不同的值
@RayBooysen 调用 ToArray 或 ToList 可以解决问题,您可以使用 Count/Length 和索引器。
请注意,@Ray 的答案在这里不适用,因为 daysDictionary<int,string>。因此它将被视为 IEnumerable<KeyValuePair<int,string>>,然后在调用 Any()First() 时按预期运行。我猜还有其他实现可以与 IEnumerable<> 表现不同。我不知道我是否遗漏了什么。
J
Jocelyn Marcotte

你可以这样做:

var days = new Dictionary<int?, string>();   // replace int by int?
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");

var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

接着 :

if (day.Key == null) {
    System.Diagnotics.Debug.Write("Couldn't find day of week");
}

M
MeatBomb

选择一个有效值列表,然后检查它是否包含您的 day.Value;像这样:

var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
days.Add(7, "Sunday");
var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

//check that FirstOrDefault has returned a valid value
if (days.Select(x=>x.Value).Contains(day.Value))
{
    //VALID
}
else
{
    System.Diagnostics.Debug.Write("Couldn't find day of week");
}

这是另一个使用键值对列表的示例:

var days = new List<KeyValuePair<int, string>>();
days.Add(new KeyValuePair<int, string>(1, "Monday"));
days.Add(new KeyValuePair<int, string>(1, "Tuesday"));
days.Add(new KeyValuePair<int, string>(1, "Sunday"));
var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));

//check that FirstOrDefault has returned a valid value
if (days.Select(x => x.Value).Contains(day.Value))
{
    //VALID
}
else
{
    System.Diagnostics.Debug.Write("Couldn't find day of week");
}

希望这对某人有帮助!


问题是关于 KeyValuePair 而不是字典
@哔叽;谢谢,你是对的。我添加了一个使用键值对列表的示例

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅