2

如果我有类似的东西:

Dictionary<SomeObject, SomeOtherObject> _mydictionary 

SomeObject有一个方法:SomeMethod()

如何在SomeMethod()不将键转换为列表并执行 ForEach 的情况下使用 lambda 表达式调用该方法。这ToList()使得它太贵了。或者,在 lambda 中等效于:

foreach(SomeObject o in _mydictionary.Keys)
  o.SomeMethod();

???

我试过了:

_mydictionary.ToList().ForEach(x => x.SomeMethod());

但这似乎太贵了ToList();

4

2 回答 2

1

使用反应式扩展(Rx)

var keys = _mydictionary.Keys;
// convert the enumerable sequence of keys to an observable sequence
var observableKeys = keys.ToObservable ();
// invoke SomeMethod for each key
await observableKeys.ForEachAsync (obj =>
    obj.SomeMethod ());

在调用第一个 SomeMethod 之前,此代码将在不阻塞枚举序列的调用的情况下执行,并且不会分配另一个集合。

不幸的是,我们正在等待交互式扩展 (Ix) 的新版本,它具有完全相同的功能,而无需从可枚举序列转换为可观察序列。

于 2012-08-22T02:58:45.427 回答
1

没有内置的扩展方法来调用void方法集合,无论是委托还是对象集合的成员。

但是,您可以相对轻松地创建一个:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
  foreach (var item in items) action(item);
}

现在您可以以 LINQish 方式调用所有这些方法:

_mydictionary.Keys.ForEach(x => x.SomeMethod());

您已经可以访问 ; 上的.Keys集合属性IDictionary<TKey,TValue>。你不需要在.ToList()任何地方打电话。


如果SomeMethod()是一个函数,并且你想创建一个结果集,那么你可以使用内置的扩展方法Select()

var results = _mydictionary.Keys.Select(x => x.SomeMethod());

正如乔治正确指出的那样,SomeMethod()除非需要,否则不会被调用 - 也就是说,除非您通过迭代它们来实际使用结果。这可以避免创建新集合的开销,但应注意避免多次枚举。

于 2012-08-22T00:33:56.693 回答