gpt4 book ai didi

c# - 未使用 Dictionary 调用 ForEach 扩展方法

转载 作者:行者123 更新时间:2023-11-30 15:16:00 25 4
gpt4 key购买 nike

我有一个包含 ValueTupleDictionary:

    private static readonly Dictionary<RELAY, (byte RelayNumber, bool IsClosed)> s_relays = new Dictionary<RELAY, (byte RelayNumber, bool IsClosed)>
{
{ RELAY.OUTPUT1, (4, false) },
{ RELAY.OUTPUT2, (9, false) },
{ RELAY.OUTPUT3, (11, false) },
};

稍后在我的代码中,我将一个或多个继电器的 IsClosed 设置为 true。我为 Dictionary 写了一个 ForEach 扩展方法:

    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
Debug.Assert(enumeration != null, $"Argument {nameof(enumeration)} cannot be null!");
Debug.Assert(action != null, $"Argument {nameof(action)} cannot be null!");

foreach (T item in enumeration)
{
action(item);
yield return item;
}
}

我想为每个关闭的继电器调用一个方法。例如,写入 Console.WriteLine:

Relays.Where(x => x.Value.IsClosed).ForEach(x => Console.WriteLine(x.Key));

但这行不通。但是,如果我包含 ToList(),下面的代码工作:

Relays.Where(x => x.Value.IsClosed).ToList().ForEach(x => Console.WriteLine(x.Key));

我错过了什么?

(我确实意识到调用的 ForEach 扩展方法在这两个示例中是不同的,第一个 [我的] 从未被调用过。)

最佳答案

在这种情况下,不同于 List<T>.ForEach()通过使用 yield return 迭代集合的实现图案,你的.ForEach实现实际上是一个延迟执行的“过滤器”,在查询完全解析之前不会执行。

从这个意义上说,它与 .Where() 极其相似方法不同的是它不是减少查询集,而是在解决查询时对其执行副作用操作。在枚举被枚举之前,两者都不会真正执行。

添加.ToList()查询结束时将按预期执行您的方法并解析查询。

或者,如果您只是想要一种方便的方式来迭代和对集合执行操作,您可以删除 yield return并简单地迭代集合并在最后返回它:

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
Debug.Assert(enumeration != null, $"Argument {nameof(enumeration)} cannot be null!");
Debug.Assert(action != null, $"Argument {nameof(action)} cannot be null!");

foreach (T item in enumeration)
{
action(item);
}

return enumeration;
}

但是,存在可能会枚举两次的风险。


同样值得注意的是你的第二个例子

Relays.Where(x => x.Value.IsClosed).ToList().ForEach(x => Console.WriteLine(x.Key));

实际上并不调用您的扩展方法。相反,它调用 List<T>.ForEach()方法。

关于c# - 未使用 Dictionary 调用 ForEach 扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50848870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com